https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/200212
>From 152e1f50d9b6a1d513658072c5bdd7b70a7f92db Mon Sep 17 00:00:00 2001 From: Joseph Huber <[email protected]> Date: Thu, 28 May 2026 10:55:53 -0500 Subject: [PATCH 1/4] [Clang] Support multilibs on Windows 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. --- clang/lib/Driver/ToolChains/MSVC.cpp | 14 ++++ .../Inputs/multilib_msvc_tree/bin/.keep | 0 .../include/x86_64-pc-windows-msvc/.keep | 0 .../x86_64-pc-windows-msvc/debug/.keep | 0 .../x86_64-pc-windows-msvc/noexcept/.keep | 0 .../x86_64-pc-windows-msvc/release/.keep | 0 clang/test/Driver/msvc-multilib.yaml | 81 +++++++++++++++++++ 7 files changed, 95 insertions(+) create mode 100644 clang/test/Driver/Inputs/multilib_msvc_tree/bin/.keep create mode 100644 clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/.keep create mode 100644 clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/debug/.keep create mode 100644 clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/noexcept/.keep create mode 100644 clang/test/Driver/Inputs/multilib_msvc_tree/include/x86_64-pc-windows-msvc/release/.keep create mode 100644 clang/test/Driver/msvc-multilib.yaml diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index f0cb01058e9c9..d7486ddeef09e 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -523,6 +523,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 { @@ -767,6 +769,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..34ac47149b19b --- /dev/null +++ b/clang/test/Driver/msvc-multilib.yaml @@ -0,0 +1,81 @@ +# 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" + +# 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: "-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" + +# 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 +... >From 9e19ef87982d6223c55377e7fa45c00666dfb62a Mon Sep 17 00:00:00 2001 From: Joseph Huber <[email protected]> Date: Thu, 28 May 2026 12:15:02 -0500 Subject: [PATCH 2/4] Fix lib paths --- clang/lib/Driver/ToolChains/MSVC.cpp | 4 ++++ clang/test/Driver/msvc-multilib.yaml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index d7486ddeef09e..7fb95ebc013c1 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)); diff --git a/clang/test/Driver/msvc-multilib.yaml b/clang/test/Driver/msvc-multilib.yaml index 34ac47149b19b..b650393003fd0 100644 --- a/clang/test/Driver/msvc-multilib.yaml +++ b/clang/test/Driver/msvc-multilib.yaml @@ -5,12 +5,16 @@ # 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" @@ -22,6 +26,8 @@ # 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 \ >From b04ce0b79c68077e81c8ed2ca9d4b5edbe24f06e Mon Sep 17 00:00:00 2001 From: Joseph Huber <[email protected]> Date: Thu, 28 May 2026 13:40:23 -0500 Subject: [PATCH 3/4] Commnets --- clang/docs/Multilib.rst | 3 ++- clang/docs/ReleaseNotes.rst | 3 +++ clang/test/Driver/print-multi-selection-flags.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) 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 11cce36a0906c..50ea2b8fdbc2d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -314,6 +314,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 multilib support + ``-fmultilib-flag=``. + New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added 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 >From e5e90f4c8a602733214dc979df59bf5a4a624e55 Mon Sep 17 00:00:00 2001 From: Joseph Huber <[email protected]> Date: Mon, 8 Jun 2026 09:25:42 -0500 Subject: [PATCH 4/4] Update ReleaseNotes.rst --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 50ea2b8fdbc2d..b740160a9d948 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -314,7 +314,7 @@ 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 multilib support +- Linux and Windows toolchains now support Clang multilib using ``-fmultilib-flag=``. New Compiler Flags _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
