Skip to content

Commit

Permalink
Add support for building with clang-cl
Browse files Browse the repository at this point in the history
This commit allows building with the Visual Studio LLVM toolchain by
passing --cc=clangcl to the configure.py script.
  • Loading branch information
solemnwarning committed Jul 25, 2024
1 parent 3e2a7ce commit 6b32b1e
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 7 deletions.
20 changes: 15 additions & 5 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2311,11 +2311,21 @@ def test_exe_extra_ldflags():
variables['includedir'],
'botan-%d' % (Version.major()), 'botan')

if cc.basename == 'msvc' and variables['cxx_abi_flags'] != '':
# MSVC linker doesn't support/need the ABI options,
# just transfer them over to just the compiler invocations
# On MSVC, the "ABI flags" should be passed to the compiler only, on other platforms, the
# ABI flags are passed to both the compiler and the linker and the compiler flags are also
# passed to the linker(?)
#
# TODO: Extend the build-data/cc/xxx.txt format to allow specifying different CFLAGS for
# different configurations, then /MD etc could be specified there rather than hijacking the ABI
# flags for it and having to special-case their exclusion from the linker command line.

if cc.basename in ('msvc', 'clangcl'):
# Move the "ABI flags" (/MD etc) into the compiler flags to exclude it from linker invocations
variables['cc_compile_flags'] = '%s %s' % (variables['cxx_abi_flags'], variables['cc_compile_flags'])
variables['cxx_abi_flags'] = ''
else:
# Append the compiler flags to the linker flags
variables['ldflags'] = '%s %s' % (variables['ldflags'], variables['cc_compile_flags'])

variables['lib_flags'] = cc.gen_lib_flags(options, variables)

Expand Down Expand Up @@ -3275,11 +3285,11 @@ def validate_options(options, info_os, info_cc, available_module_policies):
raise UserError('Option --with-pdf requires --with-sphinx')

# Warnings
if options.os == 'windows' and options.compiler != 'msvc':
if options.os == 'windows' and options.compiler not in ('msvc', 'clangcl'):
logging.warning('The windows target is oriented towards MSVC; maybe you want --os=cygwin or --os=mingw')

if options.msvc_runtime:
if options.compiler != 'msvc':
if options.compiler != 'msvc' and options.compiler != 'clangcl':

Check warning on line 3292 in configure.py

View workflow job for this annotation

GitHub Actions / Analysis (lint, gcc, ubuntu-24.04)

Pylint (refactor): R1714 Consider merging these comparisons with 'in' by using 'options.compiler not in ('msvc', 'clangcl')'. Use a set instead if elements are hashable. (consider-using-in)
raise UserError("Makes no sense to specify MSVC runtime for %s" % (options.compiler))

if options.msvc_runtime not in ['MT', 'MD', 'MTd', 'MDd']:
Expand Down
102 changes: 102 additions & 0 deletions src/build-data/cc/clangcl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
macro_name CLANG

minimum_supported_version 19.30

binary_name clang-cl
linker_name lld-link

output_to_object "/Fo"
output_to_exe "/OUT:"

add_include_dir_option "/I"
add_system_include_dir_option "/external:W0 /external:I"
add_lib_dir_option "/LIBPATH:"
add_compile_definition_option "/D"
add_lib_option "%s.lib"

compile_flags "/nologo /c"

supports_gcc_inline_asm yes

optimization_flags "/O2 /Oi"
size_optimization_flags "/O1 /Os"

# for debug info in the object file (required if using sccache):
#debug_info_flags "/Z7"

# for using a PDB file:
debug_info_flags "/Zi /FS"

preproc_flags "/nologo /EP"

lang_flags "/std:c++20 /EHs /GR"

# 4251: STL types used in DLL interface
# 4275: ???
# 5072: ASan without debug info
warning_flags "/W4 /wd4251 /wd4275 /wd5072"

werror_flags "/WX"

visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)"
visibility_attribute "__declspec(dllimport)"

# Include dependency tracking for Ninja
# See: https://ninja-build.org/manual.html#ref_headers
ninja_header_deps_style 'msvc'
header_deps_flag '/showIncludes'

ar_command lib
ar_options "/nologo"
ar_output_to "/OUT:"

<sanitizers>
default -> address

iterator -> "/D_ITERATOR_DEBUG_LEVEL=1"
address -> "/fsanitize=address"
</sanitizers>

<isa_flags>
sse2 -> "-msse2"
ssse3 -> "-mssse3"
sse41 -> "-msse4.1"
sse42 -> "-msse4.2"
avx2 -> "-mavx2"
avx512 -> "-mavx512f -mavx512bw -mavx512dq -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vl -mavx512ifma"

bmi2 -> "-mbmi -mbmi2"
aesni -> "-maes -mpclmul"
rdrand -> "-mrdrnd"
rdseed -> "-mrdseed"
sha -> "-msha"
altivec -> "-maltivec"

arm64:armv8crypto -> "-march=armv8+crypto"
arm64:armv8sha512 -> "-march=armv8.2-a+sha3"

arm32:neon -> "-mfpu=neon"
arm64:neon -> ""
</isa_flags>

<lib_flags>
debug -> "/Fd%{build_dir}/%{libname}.pdb"
</lib_flags>

<so_link_commands>
default -> "{linker} /DLL"
default-debug -> "{linker} /DLL /DEBUG"
</so_link_commands>

<binary_link_commands>
default -> "{linker}"
default-debug -> "{linker} /DEBUG"
</binary_link_commands>

<mach_abi_linking>
all -> "/bigobj"

# These can be overridden with --msvc-runtime option
rt -> "/MD"
rt-debug -> "/MDd"
</mach_abi_linking>
2 changes: 1 addition & 1 deletion src/build-data/makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LANG_EXE_FLAGS = %{cc_lang_binary_linker_flags}
CXXFLAGS = %{cc_compile_flags}
WARN_FLAGS = %{cc_warning_flags}
LIB_FLAGS = %{lib_flags}
LDFLAGS = %{ldflags} %{cc_compile_flags}
LDFLAGS = %{ldflags}

EXE_LINK_CMD = %{exe_link_cmd}

Expand Down
2 changes: 1 addition & 1 deletion src/build-data/ninja.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ LANG_EXE_FLAGS = %{cc_lang_binary_linker_flags}
CXXFLAGS = %{cc_compile_flags}
WARN_FLAGS = %{cc_warning_flags}

LDFLAGS = %{ldflags} %{cc_compile_flags}
LDFLAGS = %{ldflags}

EXE_LINK_CMD = %{exe_link_cmd}

Expand Down
14 changes: 14 additions & 0 deletions src/lib/math/bigint/big_ops2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@
#include <botan/internal/mp_core.h>
#include <algorithm>

/* This hack works around an undefined reference to __udivti3() when compiling for 64-bit Windows
* using clang-cl, see:
*
* https://github.com/llvm/llvm-project/issues/25679
* https://stackoverflow.com/questions/68676184/clang-cl-error-lld-link-error-undefined-symbol-divti3
*
* I couldn't come up with a way to embed this into the build info files without extending
* configure.py to allow cpu-specific libs in the compiler info or os+cc+arch-specific libs in the
* module info. Hopefully this can go away when the above Clang issue is fixed anyway.
*/
#if defined(_MSC_VER) && defined(_WIN64) && defined(__clang__)
#pragma comment(lib, "clang_rt.builtins-x86_64.lib")
#endif

namespace Botan {

BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/x509/certstor_flatfile/certstor_flatfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define BOTAN_CERT_STORE_FLATFILE_H_

#include <botan/certstor.h>
#include <botan/pkix_types.h>

#include <map>
#include <memory>
Expand Down

0 comments on commit 6b32b1e

Please sign in to comment.