Author: Joseph Huber Date: 2026-06-09T08:35:07-05:00 New Revision: ee39c604feff48ce4b5396f8a7c51da86768479b
URL: https://github.com/llvm/llvm-project/commit/ee39c604feff48ce4b5396f8a7c51da86768479b DIFF: https://github.com/llvm/llvm-project/commit/ee39c604feff48ce4b5396f8a7c51da86768479b.diff LOG: [Clang] Support multilibs on Windows (#200212) Summary: This was pushed to a follow-up, and I think the previous has lingered long enough to expand this to Windows. the per-target runtime directory this uses is default-off, but nothing stops us from just providing this. The interest in this is for ROCm builds on Windows to be able to provide asan / debug builds the same way on Linux. Added: clang/test/Driver/Inputs/multilib_msvc_tree/bin/.keep clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/.keep clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/debug/.keep clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/noexcept/.keep clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/release/.keep clang/test/Driver/msvc-multilib.yaml Modified: clang/docs/Multilib.rst clang/docs/ReleaseNotes.rst clang/lib/Driver/ToolChains/MSVC.cpp clang/test/Driver/print-multi-selection-flags.c Removed: ################################################################################ diff --git a/clang/docs/Multilib.rst b/clang/docs/Multilib.rst index d36b73dce68cd..06c43e720ab87 100644 --- a/clang/docs/Multilib.rst +++ b/clang/docs/Multilib.rst @@ -48,7 +48,8 @@ EXPERIMENTAL Multilib via configuration file ============================================ Some Clang toolchains support loading multilib configuration from a -``multilib.yaml`` configuration file. +``multilib.yaml`` configuration file. This is currently supported on Linux, +Windows, and Baremetal toolchains. A ``multilib.yaml`` configuration file specifies which multilib variants are available, their relative location, what compilation options were used to build diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8a00b235860e4..a569572af43ca 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -325,6 +325,9 @@ Non-comprehensive list of changes in this release - Updated support for Unicode from 15.1 to 18.0. +- Linux and Windows toolchains now support Clang multilibs using + ``-fmultilib-flag=``. + - The SafeStack builtins ``__builtin___get_unsafe_stack_ptr``, ``__builtin___get_unsafe_stack_bottom``, ``__builtin___get_unsafe_stack_top``, and ``__builtin___get_unsafe_stack_start`` are now deprecated. Use the diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 8141f9f132421..9439e30da765c 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -205,6 +205,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (TC.getVFS().exists(LibPath)) CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath)); } + for (const auto &LibPath : TC.getFilePaths()) { + if (LibPath.length() > 0) + CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath)); + } auto CRTPath = TC.getCompilerRTPath(); if (TC.getVFS().exists(CRTPath)) CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath)); @@ -523,6 +527,8 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolsVersion, VCToolChainPath, VSLayout) || llvm::findVCToolChainViaRegistry(VCToolChainPath, VSLayout); + + loadMultilibsFromYAML(Args, D); } Tool *MSVCToolChain::buildLinker() const { @@ -774,6 +780,18 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; + // Add multilib variant include paths in priority order. + for (const Multilib &M : getOrderedMultilibs()) { + if (M.isDefault()) + continue; + if (std::optional<std::string> StdlibIncDir = getStdlibIncludePath()) { + SmallString<128> Dir(*StdlibIncDir); + llvm::sys::path::append(Dir, M.includeSuffix()); + if (getDriver().getVFS().exists(Dir)) + addSystemInclude(DriverArgs, CC1Args, Dir); + } + } + // Honor %INCLUDE% and %EXTERNAL_INCLUDE%. It should have essential search // paths set by vcvarsall.bat. Skip if the user expressly set any of the // Windows SDK or VC Tools options. diff --git a/clang/test/Driver/Inputs/multilib_msvc_tree/bin/.keep b/clang/test/Driver/Inputs/multilib_msvc_tree/bin/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/.keep b/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/debug/.keep b/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/debug/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/noexcept/.keep b/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/noexcept/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/release/.keep b/clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/release/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/msvc-multilib.yaml b/clang/test/Driver/msvc-multilib.yaml new file mode 100644 index 0000000000000..b650393003fd0 --- /dev/null +++ b/clang/test/Driver/msvc-multilib.yaml @@ -0,0 +1,87 @@ +# Basic selection where -fmultilib-flag=debug selects the debug variant. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c %s -### -o /dev/null 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc -fmultilib-flag=debug \ +# RUN: -ccc-install-dir %S/Inputs/multilib_msvc_tree/bin \ +# RUN: | FileCheck --check-prefix=CHECK-DEBUG %s +# CHECK-DEBUG: "-cc1" "-triple" "x86_64-pc-windows-msvc +# CHECK-DEBUG: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/debug" +# CHECK-DEBUG: "-libpath:{{[^"]*}}/debug" + +# Default behavior where no variant path is prepended. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c %s -### -o /dev/null 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc \ +# RUN: -ccc-install-dir %S/Inputs/multilib_msvc_tree/bin \ +# RUN: | FileCheck --check-prefix=CHECK-DEFAULT %s +# CHECK-DEFAULT-NOT: "-libpath:{{[^"]*}}/debug" +# CHECK-DEFAULT-NOT: "-libpath:{{[^"]*}}/release" +# CHECK-DEFAULT-NOT: "-libpath:{{[^"]*}}/noexcept" +# CHECK-DEFAULT-NOT: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/debug" +# CHECK-DEFAULT-NOT: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/release" +# CHECK-DEFAULT-NOT: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/noexcept" + +# Multiple matches stacking on top of each-other. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c %s -### -o /dev/null 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc -fmultilib-flag=debug -fno-exceptions \ +# RUN: -ccc-install-dir %S/Inputs/multilib_msvc_tree/bin \ +# RUN: | FileCheck --check-prefix=CHECK-LAYERED %s +# CHECK-LAYERED: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/noexcept" +# CHECK-LAYERED-SAME: "-internal-isystem" "{{[^"]*}}{{[/\\]}}x86_64-pc-windows-msvc/debug" +# CHECK-LAYERED: "-libpath:{{[^"]*}}/noexcept" +# CHECK-LAYERED-SAME: "-libpath:{{[^"]*}}/debug" + +# Lists selected variant directories. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc -fmultilib-flag=debug \ +# RUN: | FileCheck --check-prefix=CHECK-PRINT-DIR %s +# CHECK-PRINT-DIR: debug + +# Lists all non-default variants with flags. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-lib 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc \ +# RUN: | FileCheck --check-prefix=CHECK-PRINT-LIB %s +# CHECK-PRINT-LIB: debug;@fmultilib-flag=debug +# CHECK-PRINT-LIB: release;@fmultilib-flag=release +# CHECK-PRINT-LIB: noexcept;@fno-exceptions + +# Error emitted when custom flag value is invalid. +# RUN: not %clang --multi-lib-config=%s -no-canonical-prefixes -x c %s -### -o /dev/null 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc -fmultilib-flag=nonexistent \ +# RUN: | FileCheck --check-prefix=CHECK-NOMATCH %s +# CHECK-NOMATCH: error: unsupported option '-fmultilib-flag=nonexistent' + +# Check exclusivity so that only one of debug/release selected. +# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \ +# RUN: --target=x86_64-pc-windows-msvc -fmultilib-flag=release \ +# RUN: | FileCheck --check-prefix=CHECK-EXCLUSIVE %s +# CHECK-EXCLUSIVE: release +# CHECK-EXCLUSIVE-NOT: debug + +--- +MultilibVersion: 1.0 + +Groups: +- Name: build-type + Type: Exclusive + +Variants: +- Dir: . + Flags: [] +- Dir: debug + Flags: [-fmultilib-flag=debug] + Group: build-type +- Dir: release + Flags: [-fmultilib-flag=release] + Group: build-type +- Dir: noexcept + Flags: [-fno-exceptions] + +Mappings: [] + +Flags: +- Name: build-type + Values: + - Name: none + - Name: debug + - Name: release + Default: none +... diff --git a/clang/test/Driver/print-multi-selection-flags.c b/clang/test/Driver/print-multi-selection-flags.c index 64efddad878c5..ba7b325892f9c 100644 --- a/clang/test/Driver/print-multi-selection-flags.c +++ b/clang/test/Driver/print-multi-selection-flags.c @@ -1,6 +1,9 @@ // RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=aarch64-linux -fc++-abi=itanium -fsanitize=address | FileCheck --check-prefix=CHECK-LINUX %s // CHECK-LINUX: --target=aarch64-unknown-linux +// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=x86_64-pc-windows-msvc -fc++-abi=itanium -fsanitize=address | FileCheck --check-prefix=CHECK-WINDOWS %s +// CHECK-WINDOWS: --target=x86_64-pc-windows-msvc + // RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=aarch64-fuchsia -fsanitize=hwaddress | FileCheck --check-prefix=CHECK-FUCHSIA %s // CHECK-FUCHSIA: --target=aarch64-unknown-fuchsia _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
