Skip to content

Commit 0bc7cd4

Browse files
authored
[flang] Add runtimes using --dependent-lib on MSVC targets (#72519)
This patch uses the added --dependent-lib support to add the relevant runtimes on MSVC targets as `/DEFAULTLIB:` sections in the object file rather than on the link line. This should help CMake support for flang on Windows. Fixes #63741 Fixes #68017
1 parent 6727526 commit 0bc7cd4

File tree

15 files changed

+112
-86
lines changed

15 files changed

+112
-86
lines changed

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -977,47 +977,11 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
977977
return true;
978978
}
979979

980-
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
980+
void tools::addFortranRuntimeLibs(const ToolChain &TC,
981981
llvm::opt::ArgStringList &CmdArgs) {
982-
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
983-
CmdArgs.push_back(Args.MakeArgString(
984-
"/DEFAULTLIB:" + TC.getCompilerRTBasename(Args, "builtins")));
985-
unsigned RTOptionID = options::OPT__SLASH_MT;
986-
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
987-
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
988-
.Case("static", options::OPT__SLASH_MT)
989-
.Case("static_dbg", options::OPT__SLASH_MTd)
990-
.Case("dll", options::OPT__SLASH_MD)
991-
.Case("dll_dbg", options::OPT__SLASH_MDd)
992-
.Default(options::OPT__SLASH_MT);
993-
}
994-
switch (RTOptionID) {
995-
case options::OPT__SLASH_MT:
996-
CmdArgs.push_back("/DEFAULTLIB:libcmt");
997-
CmdArgs.push_back("Fortran_main.static.lib");
998-
CmdArgs.push_back("FortranRuntime.static.lib");
999-
CmdArgs.push_back("FortranDecimal.static.lib");
1000-
break;
1001-
case options::OPT__SLASH_MTd:
1002-
CmdArgs.push_back("/DEFAULTLIB:libcmtd");
1003-
CmdArgs.push_back("Fortran_main.static_dbg.lib");
1004-
CmdArgs.push_back("FortranRuntime.static_dbg.lib");
1005-
CmdArgs.push_back("FortranDecimal.static_dbg.lib");
1006-
break;
1007-
case options::OPT__SLASH_MD:
1008-
CmdArgs.push_back("/DEFAULTLIB:msvcrt");
1009-
CmdArgs.push_back("Fortran_main.dynamic.lib");
1010-
CmdArgs.push_back("FortranRuntime.dynamic.lib");
1011-
CmdArgs.push_back("FortranDecimal.dynamic.lib");
1012-
break;
1013-
case options::OPT__SLASH_MDd:
1014-
CmdArgs.push_back("/DEFAULTLIB:msvcrtd");
1015-
CmdArgs.push_back("Fortran_main.dynamic_dbg.lib");
1016-
CmdArgs.push_back("FortranRuntime.dynamic_dbg.lib");
1017-
CmdArgs.push_back("FortranDecimal.dynamic_dbg.lib");
1018-
break;
1019-
}
1020-
} else {
982+
// These are handled earlier on Windows by telling the frontend driver to add
983+
// the correct libraries to link against as dependents in the object file.
984+
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1021985
CmdArgs.push_back("-lFortran_main");
1022986
CmdArgs.push_back("-lFortranRuntime");
1023987
CmdArgs.push_back("-lFortranDecimal");

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, const llvm::opt::ArgList &Args,
119+
void addFortranRuntimeLibs(const ToolChain &TC,
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(), Args, CmdArgs);
681+
addFortranRuntimeLibs(getToolChain(), 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, Args, CmdArgs);
156+
addFortranRuntimeLibs(ToolChain, CmdArgs);
157157
CmdArgs.push_back("-lm");
158158
}
159159

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,59 @@ void Flang::AddAArch64TargetArgs(const ArgList &Args,
204204
}
205205
}
206206

207+
static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
208+
ArgStringList &CmdArgs) {
209+
assert(TC.getTriple().isKnownWindowsMSVCEnvironment() &&
210+
"can only add VS runtime library on Windows!");
211+
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
212+
CmdArgs.push_back(Args.MakeArgString(
213+
"--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins")));
214+
}
215+
unsigned RTOptionID = options::OPT__SLASH_MT;
216+
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
217+
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
218+
.Case("static", options::OPT__SLASH_MT)
219+
.Case("static_dbg", options::OPT__SLASH_MTd)
220+
.Case("dll", options::OPT__SLASH_MD)
221+
.Case("dll_dbg", options::OPT__SLASH_MDd)
222+
.Default(options::OPT__SLASH_MT);
223+
}
224+
switch (RTOptionID) {
225+
case options::OPT__SLASH_MT:
226+
CmdArgs.push_back("-D_MT");
227+
CmdArgs.push_back("--dependent-lib=libcmt");
228+
CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib");
229+
CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib");
230+
CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib");
231+
break;
232+
case options::OPT__SLASH_MTd:
233+
CmdArgs.push_back("-D_MT");
234+
CmdArgs.push_back("-D_DEBUG");
235+
CmdArgs.push_back("--dependent-lib=libcmtd");
236+
CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib");
237+
CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib");
238+
CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib");
239+
break;
240+
case options::OPT__SLASH_MD:
241+
CmdArgs.push_back("-D_MT");
242+
CmdArgs.push_back("-D_DLL");
243+
CmdArgs.push_back("--dependent-lib=msvcrt");
244+
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib");
245+
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib");
246+
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib");
247+
break;
248+
case options::OPT__SLASH_MDd:
249+
CmdArgs.push_back("-D_MT");
250+
CmdArgs.push_back("-D_DEBUG");
251+
CmdArgs.push_back("-D_DLL");
252+
CmdArgs.push_back("--dependent-lib=msvcrtd");
253+
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib");
254+
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib");
255+
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib");
256+
break;
257+
}
258+
}
259+
207260
void Flang::addTargetOptions(const ArgList &Args,
208261
ArgStringList &CmdArgs) const {
209262
const ToolChain &TC = getToolChain();
@@ -267,6 +320,10 @@ void Flang::addTargetOptions(const ArgList &Args,
267320
}
268321
}
269322

323+
if (Triple.isKnownWindowsMSVCEnvironment()) {
324+
processVSRuntimeLibrary(TC, Args, CmdArgs);
325+
}
326+
270327
// TODO: Add target specific flags, ABI, mtune option etc.
271328
}
272329

clang/lib/Driver/ToolChains/FreeBSD.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
310310
// AddRunTimeLibs).
311311
if (D.IsFlangMode()) {
312312
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
313-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
313+
addFortranRuntimeLibs(ToolChain, CmdArgs);
314314
if (Profiling)
315315
CmdArgs.push_back("-lm_p");
316316
else

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
564564
// AddRunTimeLibs).
565565
if (D.IsFlangMode()) {
566566
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
567-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
567+
addFortranRuntimeLibs(ToolChain, CmdArgs);
568568
CmdArgs.push_back("-lm");
569569
}
570570

clang/lib/Driver/ToolChains/Haiku.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
118118
// AddRunTimeLibs).
119119
if (D.IsFlangMode()) {
120120
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
121-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
121+
addFortranRuntimeLibs(ToolChain, CmdArgs);
122122
}
123123

124124
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, Args, CmdArgs);
134+
addFortranRuntimeLibs(TC, 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, Args, CmdArgs);
252+
addFortranRuntimeLibs(TC, 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
@@ -325,7 +325,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
325325
// AddRunTimeLibs).
326326
if (D.IsFlangMode()) {
327327
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
328-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
328+
addFortranRuntimeLibs(ToolChain, CmdArgs);
329329
CmdArgs.push_back("-lm");
330330
}
331331

clang/lib/Driver/ToolChains/OpenBSD.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
237237
// AddRunTimeLibs).
238238
if (D.IsFlangMode()) {
239239
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
240-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
240+
addFortranRuntimeLibs(ToolChain, CmdArgs);
241241
if (Profiling)
242242
CmdArgs.push_back("-lm_p");
243243
else

clang/lib/Driver/ToolChains/Solaris.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
226226
// these dependencies need to be listed before the C runtime below.
227227
if (D.IsFlangMode()) {
228228
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
229-
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
229+
addFortranRuntimeLibs(getToolChain(), CmdArgs);
230230
CmdArgs.push_back("-lm");
231231
}
232232
if (Args.hasArg(options::OPT_fstack_protector) ||

flang/test/Driver/linker-flags.f90

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
! but it is not needed when compiling Fortran code and they might bring in
1717
! additional dependencies. Make sure its not added.
1818
! 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
2219

2320
! Compiler invocation to generate the object file
2421
! CHECK-LABEL: {{.*}} "-emit-obj"
@@ -54,37 +51,5 @@
5451
! (lld-)link.exe on Windows platforms. The suffix may not be added
5552
! when the executable is not found or on non-Windows platforms.
5653
! MSVC-LABEL: link
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
6254
! MSVC-SAME: /subsystem:console
6355
! 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]]"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
! RUN: %flang -### --target=aarch64-windows-msvc %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC
2+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=static_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DEBUG
3+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL
4+
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL-DEBUG
5+
6+
! MSVC: -fc1
7+
! MSVC-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
8+
! MSVC-SAME: -D_MT
9+
! MSVC-SAME: --dependent-lib=libcmt
10+
! MSVC-SAME: --dependent-lib=Fortran_main.static.lib
11+
! MSVC-SAME: --dependent-lib=FortranRuntime.static.lib
12+
! MSVC-SAME: --dependent-lib=FortranDecimal.static.lib
13+
14+
! MSVC-DEBUG: -fc1
15+
! MSVC-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
16+
! MSVC-DEBUG-SAME: -D_MT
17+
! MSVC-DEBUG-SAME: -D_DEBUG
18+
! MSVC-DEBUG-SAME: --dependent-lib=libcmtd
19+
! MSVC-DEBUG-SAME: --dependent-lib=Fortran_main.static_dbg.lib
20+
! MSVC-DEBUG-SAME: --dependent-lib=FortranRuntime.static_dbg.lib
21+
! MSVC-DEBUG-SAME: --dependent-lib=FortranDecimal.static_dbg.lib
22+
23+
! MSVC-DLL: -fc1
24+
! MSVC-DLL-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
25+
! MSVC-DLL-SAME: -D_MT
26+
! MSVC-DLL-SAME: -D_DLL
27+
! MSVC-DLL-SAME: --dependent-lib=msvcrt
28+
! MSVC-DLL-SAME: --dependent-lib=Fortran_main.dynamic.lib
29+
! MSVC-DLL-SAME: --dependent-lib=FortranRuntime.dynamic.lib
30+
! MSVC-DLL-SAME: --dependent-lib=FortranDecimal.dynamic.lib
31+
32+
! MSVC-DLL-DEBUG: -fc1
33+
! MSVC-DLL-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
34+
! MSVC-DLL-DEBUG-SAME: -D_MT
35+
! MSVC-DLL-DEBUG-SAME: -D_DEBUG
36+
! MSVC-DLL-DEBUG-SAME: -D_DLL
37+
! MSVC-DLL-DEBUG-SAME: --dependent-lib=msvcrtd
38+
! MSVC-DLL-DEBUG-SAME: --dependent-lib=Fortran_main.dynamic_dbg.lib
39+
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranRuntime.dynamic_dbg.lib
40+
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranDecimal.dynamic_dbg.lib

0 commit comments

Comments
 (0)