Skip to content

Commit 4605714

Browse files
committed
[flang][windows] Add option to link against specific MSVC CRT
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 601e8fd commit 4605714

File tree

19 files changed

+169
-31
lines changed

19 files changed

+169
-31
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
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

Lines changed: 38 additions & 4 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 23 additions & 0 deletions
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

Lines changed: 34 additions & 6 deletions
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()
Lines changed: 18 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 39 additions & 8 deletions
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)