diff --git a/configure.py b/configure.py
index aca1b3e3d32..ad72ecceb3a 100755
--- a/configure.py
+++ b/configure.py
@@ -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)
@@ -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':
raise UserError("Makes no sense to specify MSVC runtime for %s" % (options.compiler))
if options.msvc_runtime not in ['MT', 'MD', 'MTd', 'MDd']:
diff --git a/src/build-data/cc/clangcl.txt b/src/build-data/cc/clangcl.txt
new file mode 100644
index 00000000000..43fbc017fa7
--- /dev/null
+++ b/src/build-data/cc/clangcl.txt
@@ -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:"
+
+
+default -> address
+
+iterator -> "/D_ITERATOR_DEBUG_LEVEL=1"
+address -> "/fsanitize=address"
+
+
+
+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 -> ""
+
+
+
+debug -> "/Fd%{build_dir}/%{libname}.pdb"
+
+
+
+default -> "{linker} /DLL"
+default-debug -> "{linker} /DLL /DEBUG"
+
+
+
+default -> "{linker}"
+default-debug -> "{linker} /DEBUG"
+
+
+
+all -> "/bigobj"
+
+# These can be overridden with --msvc-runtime option
+rt -> "/MD"
+rt-debug -> "/MDd"
+
diff --git a/src/build-data/makefile.in b/src/build-data/makefile.in
index e59085667bb..9b3ac587477 100644
--- a/src/build-data/makefile.in
+++ b/src/build-data/makefile.in
@@ -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}
diff --git a/src/build-data/ninja.in b/src/build-data/ninja.in
index e2ee02ed2c2..8746b4690fe 100644
--- a/src/build-data/ninja.in
+++ b/src/build-data/ninja.in
@@ -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}
diff --git a/src/lib/math/bigint/big_ops2.cpp b/src/lib/math/bigint/big_ops2.cpp
index 1b4589f5f13..46032db8ad3 100644
--- a/src/lib/math/bigint/big_ops2.cpp
+++ b/src/lib/math/bigint/big_ops2.cpp
@@ -11,6 +11,20 @@
#include
#include
+/* 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) {
diff --git a/src/lib/x509/certstor_flatfile/certstor_flatfile.h b/src/lib/x509/certstor_flatfile/certstor_flatfile.h
index 67075bcebcb..db5547b0160 100644
--- a/src/lib/x509/certstor_flatfile/certstor_flatfile.h
+++ b/src/lib/x509/certstor_flatfile/certstor_flatfile.h
@@ -10,6 +10,7 @@
#define BOTAN_CERT_STORE_FLATFILE_H_
#include
+#include
#include