Skip to content

Commit cf1e342

Browse files
authored
[flang][windows] Add option to link against specific MSVC CRT (llvm#70833)
Currently flang's runtime libraries are only built for the specific CRT that LLVM itself was built against. This patch adds the cmake logic for building a separate runtime for each CRT configuration and adds a flag for selecting a CRT configuration to link against.
1 parent 18a0313 commit cf1e342

19 files changed

+169
-31
lines changed

clang/include/clang/Driver/Options.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -2858,7 +2858,7 @@ def fms_compatibility_version
28582858
"version number to report in _MSC_VER (0 = don't define it "
28592859
"(default))">;
28602860
def fms_runtime_lib_EQ : Joined<["-"], "fms-runtime-lib=">, Group<f_Group>,
2861-
Flags<[]>, Visibility<[ClangOption, CLOption]>,
2861+
Flags<[]>, Visibility<[ClangOption, CLOption, FlangOption]>,
28622862
Values<"static,static_dbg,dll,dll_dbg">,
28632863
HelpText<"Select Windows run-time library">,
28642864
DocBrief<[{

clang/lib/Driver/ToolChains/CommonArgs.cpp

+38-4
Original file line numberDiff line numberDiff line change
@@ -976,12 +976,46 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
976976
return true;
977977
}
978978

979-
void tools::addFortranRuntimeLibs(const ToolChain &TC,
979+
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
980980
llvm::opt::ArgStringList &CmdArgs) {
981981
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
982-
CmdArgs.push_back("Fortran_main.lib");
983-
CmdArgs.push_back("FortranRuntime.lib");
984-
CmdArgs.push_back("FortranDecimal.lib");
982+
CmdArgs.push_back(Args.MakeArgString(
983+
"/DEFAULTLIB:" + TC.getCompilerRTBasename(Args, "builtins")));
984+
unsigned RTOptionID = options::OPT__SLASH_MT;
985+
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
986+
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
987+
.Case("static", options::OPT__SLASH_MT)
988+
.Case("static_dbg", options::OPT__SLASH_MTd)
989+
.Case("dll", options::OPT__SLASH_MD)
990+
.Case("dll_dbg", options::OPT__SLASH_MDd)
991+
.Default(options::OPT__SLASH_MT);
992+
}
993+
switch (RTOptionID) {
994+
case options::OPT__SLASH_MT:
995+
CmdArgs.push_back("/DEFAULTLIB:libcmt");
996+
CmdArgs.push_back("Fortran_main.static.lib");
997+
CmdArgs.push_back("FortranRuntime.static.lib");
998+
CmdArgs.push_back("FortranDecimal.static.lib");
999+
break;
1000+
case options::OPT__SLASH_MTd:
1001+
CmdArgs.push_back("/DEFAULTLIB:libcmtd");
1002+
CmdArgs.push_back("Fortran_main.static_dbg.lib");
1003+
CmdArgs.push_back("FortranRuntime.static_dbg.lib");
1004+
CmdArgs.push_back("FortranDecimal.static_dbg.lib");
1005+
break;
1006+
case options::OPT__SLASH_MD:
1007+
CmdArgs.push_back("/DEFAULTLIB:msvcrt");
1008+
CmdArgs.push_back("Fortran_main.dynamic.lib");
1009+
CmdArgs.push_back("FortranRuntime.dynamic.lib");
1010+
CmdArgs.push_back("FortranDecimal.dynamic.lib");
1011+
break;
1012+
case options::OPT__SLASH_MDd:
1013+
CmdArgs.push_back("/DEFAULTLIB:msvcrtd");
1014+
CmdArgs.push_back("Fortran_main.dynamic_dbg.lib");
1015+
CmdArgs.push_back("FortranRuntime.dynamic_dbg.lib");
1016+
CmdArgs.push_back("FortranDecimal.dynamic_dbg.lib");
1017+
break;
1018+
}
9851019
} else {
9861020
CmdArgs.push_back("-lFortran_main");
9871021
CmdArgs.push_back("-lFortranRuntime");

clang/lib/Driver/ToolChains/CommonArgs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
116116
bool IsOffloadingHost = false, bool GompNeedsRT = false);
117117

118118
/// Adds Fortran runtime libraries to \p CmdArgs.
119-
void addFortranRuntimeLibs(const ToolChain &TC,
119+
void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args,
120120
llvm::opt::ArgStringList &CmdArgs);
121121

122122
/// Adds the path for the Fortran runtime libraries to \p CmdArgs.

clang/lib/Driver/ToolChains/Darwin.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
678678
// to generate executables.
679679
if (getToolChain().getDriver().IsFlangMode()) {
680680
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
681-
addFortranRuntimeLibs(getToolChain(), CmdArgs);
681+
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
682682
}
683683

684684
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))

clang/lib/Driver/ToolChains/DragonFly.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
153153
// AddRunTimeLibs).
154154
if (D.IsFlangMode()) {
155155
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
156-
addFortranRuntimeLibs(ToolChain, CmdArgs);
156+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
157157
CmdArgs.push_back("-lm");
158158
}
159159

clang/lib/Driver/ToolChains/FreeBSD.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
308308
// AddRunTimeLibs).
309309
if (D.IsFlangMode()) {
310310
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
311-
addFortranRuntimeLibs(ToolChain, CmdArgs);
311+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
312312
if (Profiling)
313313
CmdArgs.push_back("-lm_p");
314314
else

clang/lib/Driver/ToolChains/Gnu.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
584584
// AddRunTimeLibs).
585585
if (D.IsFlangMode()) {
586586
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
587-
addFortranRuntimeLibs(ToolChain, CmdArgs);
587+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
588588
CmdArgs.push_back("-lm");
589589
}
590590

clang/lib/Driver/ToolChains/Haiku.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
104104
// AddRunTimeLibs).
105105
if (D.IsFlangMode()) {
106106
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
107-
addFortranRuntimeLibs(ToolChain, CmdArgs);
107+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
108108
}
109109

110110
CmdArgs.push_back("-lgcc");

clang/lib/Driver/ToolChains/MSVC.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
131131

132132
if (C.getDriver().IsFlangMode()) {
133133
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
134-
addFortranRuntimeLibs(TC, CmdArgs);
134+
addFortranRuntimeLibs(TC, Args, CmdArgs);
135135

136136
// Inform the MSVC linker that we're generating a console application, i.e.
137137
// one with `main` as the "user-defined" entry point. The `main` function is

clang/lib/Driver/ToolChains/MinGW.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
249249

250250
if (C.getDriver().IsFlangMode()) {
251251
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
252-
addFortranRuntimeLibs(TC, CmdArgs);
252+
addFortranRuntimeLibs(TC, Args, CmdArgs);
253253
}
254254

255255
// TODO: Add profile stuff here

clang/lib/Driver/ToolChains/NetBSD.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
324324
// AddRunTimeLibs).
325325
if (D.IsFlangMode()) {
326326
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
327-
addFortranRuntimeLibs(ToolChain, CmdArgs);
327+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
328328
CmdArgs.push_back("-lm");
329329
}
330330

clang/lib/Driver/ToolChains/OpenBSD.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
223223
// AddRunTimeLibs).
224224
if (D.IsFlangMode()) {
225225
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
226-
addFortranRuntimeLibs(ToolChain, CmdArgs);
226+
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
227227
if (Profiling)
228228
CmdArgs.push_back("-lm_p");
229229
else

clang/lib/Driver/ToolChains/Solaris.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
228228
// to generate executables. As Fortran runtime depends on the C runtime,
229229
// these dependencies need to be listed before the C runtime below.
230230
if (D.IsFlangMode()) {
231-
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
232-
addFortranRuntimeLibs(ToolChain, CmdArgs);
231+
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
232+
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
233233
CmdArgs.push_back("-lm");
234234
}
235235
if (Args.hasArg(options::OPT_fstack_protector) ||

flang/lib/Decimal/CMakeLists.txt

+23
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,26 @@ add_flang_library(FortranDecimal INSTALL_WITH_TOOLCHAIN
5353
binary-to-decimal.cpp
5454
decimal-to-binary.cpp
5555
)
56+
57+
if (DEFINED MSVC)
58+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
59+
add_flang_library(FortranDecimal.static INSTALL_WITH_TOOLCHAIN
60+
binary-to-decimal.cpp
61+
decimal-to-binary.cpp
62+
)
63+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
64+
add_flang_library(FortranDecimal.dynamic INSTALL_WITH_TOOLCHAIN
65+
binary-to-decimal.cpp
66+
decimal-to-binary.cpp
67+
)
68+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
69+
add_flang_library(FortranDecimal.static_dbg INSTALL_WITH_TOOLCHAIN
70+
binary-to-decimal.cpp
71+
decimal-to-binary.cpp
72+
)
73+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL)
74+
add_flang_library(FortranDecimal.dynamic_dbg INSTALL_WITH_TOOLCHAIN
75+
binary-to-decimal.cpp
76+
decimal-to-binary.cpp
77+
)
78+
endif()

flang/runtime/CMakeLists.txt

+34-6
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,38 @@ if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "off")
274274
endif()
275275
endif()
276276

277-
add_flang_library(FortranRuntime
278-
${sources}
279-
LINK_LIBS
280-
FortranDecimal
277+
if (NOT DEFINED MSVC)
278+
add_flang_library(FortranRuntime
279+
${sources}
280+
LINK_LIBS
281+
FortranDecimal
281282

282-
INSTALL_WITH_TOOLCHAIN
283-
)
283+
INSTALL_WITH_TOOLCHAIN
284+
)
285+
else()
286+
add_flang_library(FortranRuntime
287+
${sources}
288+
LINK_LIBS
289+
FortranDecimal
290+
)
291+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
292+
add_flang_library(FortranRuntime.static ${sources}
293+
LINK_LIBS
294+
FortranDecimal.static
295+
INSTALL_WITH_TOOLCHAIN)
296+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
297+
add_flang_library(FortranRuntime.dynamic ${sources}
298+
LINK_LIBS
299+
FortranDecimal.dynamic
300+
INSTALL_WITH_TOOLCHAIN)
301+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
302+
add_flang_library(FortranRuntime.static_dbg ${sources}
303+
LINK_LIBS
304+
FortranDecimal.static_dbg
305+
INSTALL_WITH_TOOLCHAIN)
306+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL)
307+
add_flang_library(FortranRuntime.dynamic_dbg ${sources}
308+
LINK_LIBS
309+
FortranDecimal.dynamic_dbg
310+
INSTALL_WITH_TOOLCHAIN)
311+
endif()
+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
11
add_flang_library(Fortran_main STATIC INSTALL_WITH_TOOLCHAIN
22
Fortran_main.c
33
)
4+
if (DEFINED MSVC)
5+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
6+
add_flang_library(Fortran_main.static STATIC INSTALL_WITH_TOOLCHAIN
7+
Fortran_main.c
8+
)
9+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
10+
add_flang_library(Fortran_main.dynamic STATIC INSTALL_WITH_TOOLCHAIN
11+
Fortran_main.c
12+
)
13+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
14+
add_flang_library(Fortran_main.static_dbg STATIC INSTALL_WITH_TOOLCHAIN
15+
Fortran_main.c
16+
)
17+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL)
18+
add_flang_library(Fortran_main.dynamic_dbg STATIC INSTALL_WITH_TOOLCHAIN
19+
Fortran_main.c
20+
)
21+
endif()

flang/test/Driver/driver-help-hidden.f90

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
! CHECK-NEXT: -flto=jobserver Enable LTO in 'full' mode
6262
! CHECK-NEXT: -flto=<value> Set LTO mode
6363
! CHECK-NEXT: -flto Enable LTO in 'full' mode
64+
! CHECK-NEXT: -fms-runtime-lib=<value>
65+
! CHECK-NEXT: Select Windows run-time library
6466
! CHECK-NEXT: -fno-alias-analysis Do not pass alias information on to LLVM (default for unoptimized builds)
6567
! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE
6668
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics

flang/test/Driver/driver-help.f90

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
! HELP-NEXT: -flto=jobserver Enable LTO in 'full' mode
5252
! HELP-NEXT: -flto=<value> Set LTO mode
5353
! HELP-NEXT: -flto Enable LTO in 'full' mode
54+
! HELP-NEXT: -fms-runtime-lib=<value>
55+
! HELP-NEXT: Select Windows run-time library
5456
! HELP-NEXT: -fno-alias-analysis Do not pass alias information on to LLVM (default for unoptimized builds)
5557
! HELP-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE
5658
! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics

flang/test/Driver/linker-flags.f90

+39-8
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
! RUN: %flang -### --target=x86_64-unknown-haiku %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,HAIKU
1313
! RUN: %flang -### --target=x86_64-windows-gnu %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MINGW
1414

15-
! NOTE: Clang's driver library, clangDriver, usually adds 'libcmt' and
16-
! 'oldnames' on Windows, but they are not needed when compiling
17-
! Fortran code and they might bring in additional dependencies.
18-
! Make sure they're not added.
19-
! RUN: %flang -### --target=aarch64-windows-msvc -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not libcmt --implicit-check-not oldnames
15+
! NOTE: Clang's driver library, clangDriver, usually adds 'oldnames' on Windows,
16+
! but it is not needed when compiling Fortran code and they might bring in
17+
! additional dependencies. Make sure its not added.
18+
! RUN: %flang -### --target=aarch64-windows-msvc -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not oldnames
19+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=static_dbg -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DEBUG --implicit-check-not oldnames
20+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DLL --implicit-check-not oldnames
21+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DLL-DEBUG --implicit-check-not oldnames
2022

2123
! Compiler invocation to generate the object file
2224
! CHECK-LABEL: {{.*}} "-emit-obj"
@@ -52,8 +54,37 @@
5254
! (lld-)link.exe on Windows platforms. The suffix may not be added
5355
! when the executable is not found or on non-Windows platforms.
5456
! MSVC-LABEL: link
55-
! MSVC-SAME: Fortran_main.lib
56-
! MSVC-SAME: FortranRuntime.lib
57-
! MSVC-SAME: FortranDecimal.lib
57+
! MSVC-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
58+
! MSVC-SAME: /DEFAULTLIB:libcmt
59+
! MSVC-SAME: Fortran_main.static.lib
60+
! MSVC-SAME: FortranRuntime.static.lib
61+
! MSVC-SAME: FortranDecimal.static.lib
5862
! MSVC-SAME: /subsystem:console
5963
! MSVC-SAME: "[[object_file]]"
64+
65+
! MSVC-DEBUG-LABEL: link
66+
! MSVC-DEBUG-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
67+
! MSVC-DEBUG-SAME: /DEFAULTLIB:libcmtd
68+
! MSVC-DEBUG-SAME: Fortran_main.static_dbg.lib
69+
! MSVC-DEBUG-SAME: FortranRuntime.static_dbg.lib
70+
! MSVC-DEBUG-SAME: FortranDecimal.static_dbg.lib
71+
! MSVC-DEBUG-SAME: /subsystem:console
72+
! MSVC-DEBUG-SAME: "[[object_file]]"
73+
74+
! MSVC-DLL-LABEL: link
75+
! MSVC-DLL-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
76+
! MSVC-DLL-SAME: /DEFAULTLIB:msvcrt
77+
! MSVC-DLL-SAME: Fortran_main.dynamic.lib
78+
! MSVC-DLL-SAME: FortranRuntime.dynamic.lib
79+
! MSVC-DLL-SAME: FortranDecimal.dynamic.lib
80+
! MSVC-DLL-SAME: /subsystem:console
81+
! MSVC-DLL-SAME: "[[object_file]]"
82+
83+
! MSVC-DLL-DEBUG-LABEL: link
84+
! MSVC-DLL-DEBUG-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
85+
! MSVC-DLL-DEBUG-SAME: /DEFAULTLIB:msvcrtd
86+
! MSVC-DLL-DEBUG-SAME: Fortran_main.dynamic_dbg.lib
87+
! MSVC-DLL-DEBUG-SAME: FortranRuntime.dynamic_dbg.lib
88+
! MSVC-DLL-DEBUG-SAME: FortranDecimal.dynamic_dbg.lib
89+
! MSVC-DLL-DEBUG-SAME: /subsystem:console
90+
! MSVC-DLL-DEBUG-SAME: "[[object_file]]"

0 commit comments

Comments
 (0)