Skip to content

Commit 71bbfab

Browse files
authored
[flang][nfc] Refactor linker invocation logic (#75534)
Refactor how the Fortran runtime libs are added to the linker invocation. This is a non-functional change.
1 parent aeb4821 commit 71bbfab

File tree

2 files changed

+79
-65
lines changed

2 files changed

+79
-65
lines changed

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 75 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,73 +1116,87 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
11161116
return true;
11171117
}
11181118

1119+
/// Determines if --whole-archive is active in the list of arguments.
1120+
static bool isWholeArchivePresent(const ArgList &Args) {
1121+
bool WholeArchiveActive = false;
1122+
for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) {
1123+
if (Arg) {
1124+
for (StringRef ArgValue : Arg->getValues()) {
1125+
if (ArgValue == "--whole-archive")
1126+
WholeArchiveActive = true;
1127+
if (ArgValue == "--no-whole-archive")
1128+
WholeArchiveActive = false;
1129+
}
1130+
}
1131+
}
1132+
1133+
return WholeArchiveActive;
1134+
}
1135+
1136+
/// Add Fortran runtime libs for MSVC
1137+
static void addFortranRuntimeLibsMSVC(const ArgList &Args,
1138+
llvm::opt::ArgStringList &CmdArgs) {
1139+
unsigned RTOptionID = options::OPT__SLASH_MT;
1140+
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
1141+
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
1142+
.Case("static", options::OPT__SLASH_MT)
1143+
.Case("static_dbg", options::OPT__SLASH_MTd)
1144+
.Case("dll", options::OPT__SLASH_MD)
1145+
.Case("dll_dbg", options::OPT__SLASH_MDd)
1146+
.Default(options::OPT__SLASH_MT);
1147+
}
1148+
switch (RTOptionID) {
1149+
case options::OPT__SLASH_MT:
1150+
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib");
1151+
break;
1152+
case options::OPT__SLASH_MTd:
1153+
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib");
1154+
break;
1155+
case options::OPT__SLASH_MD:
1156+
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib");
1157+
break;
1158+
case options::OPT__SLASH_MDd:
1159+
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib");
1160+
break;
1161+
}
1162+
}
1163+
1164+
/// Add Fortran runtime libs
11191165
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
11201166
llvm::opt::ArgStringList &CmdArgs) {
1121-
// These are handled earlier on Windows by telling the frontend driver to add
1122-
// the correct libraries to link against as dependents in the object file.
1123-
1124-
// if -fno-fortran-main has been passed, skip linking Fortran_main.a
1125-
bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main);
1167+
// 1. Link FortranRuntime and FortranDecimal
1168+
// These are handled earlier on Windows by telling the frontend driver to
1169+
// add the correct libraries to link against as dependents in the object
1170+
// file.
11261171
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1127-
if (LinkFortranMain) {
1128-
// The --whole-archive option needs to be part of the link line to
1129-
// make sure that the main() function from Fortran_main.a is pulled
1130-
// in by the linker. Determine if --whole-archive is active when
1131-
// flang will try to link Fortran_main.a. If it is, don't add the
1132-
// --whole-archive flag to the link line. If it's not, add a proper
1133-
// --whole-archive/--no-whole-archive bracket to the link line.
1134-
bool WholeArchiveActive = false;
1135-
for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) {
1136-
if (Arg) {
1137-
for (StringRef ArgValue : Arg->getValues()) {
1138-
if (ArgValue == "--whole-archive")
1139-
WholeArchiveActive = true;
1140-
if (ArgValue == "--no-whole-archive")
1141-
WholeArchiveActive = false;
1142-
}
1143-
}
1144-
}
1172+
CmdArgs.push_back("-lFortranRuntime");
1173+
CmdArgs.push_back("-lFortranDecimal");
1174+
}
11451175

1146-
// TODO: Find an equivalent of `--whole-archive` for Darwin.
1147-
if (!WholeArchiveActive && !TC.getTriple().isMacOSX()) {
1148-
CmdArgs.push_back("--whole-archive");
1149-
CmdArgs.push_back("-lFortran_main");
1150-
CmdArgs.push_back("--no-whole-archive");
1151-
} else {
1152-
CmdArgs.push_back("-lFortran_main");
1153-
}
1176+
// 2. Link FortranMain
1177+
// If -fno-fortran-main has been passed, skip linking Fortran_main.a
1178+
if (Args.hasArg(options::OPT_no_fortran_main))
1179+
return;
11541180

1155-
// Perform regular linkage of the remaining runtime libraries.
1156-
CmdArgs.push_back("-lFortranRuntime");
1157-
CmdArgs.push_back("-lFortranDecimal");
1158-
}
1159-
} else {
1160-
if (LinkFortranMain) {
1161-
unsigned RTOptionID = options::OPT__SLASH_MT;
1162-
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
1163-
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
1164-
.Case("static", options::OPT__SLASH_MT)
1165-
.Case("static_dbg", options::OPT__SLASH_MTd)
1166-
.Case("dll", options::OPT__SLASH_MD)
1167-
.Case("dll_dbg", options::OPT__SLASH_MDd)
1168-
.Default(options::OPT__SLASH_MT);
1169-
}
1170-
switch (RTOptionID) {
1171-
case options::OPT__SLASH_MT:
1172-
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib");
1173-
break;
1174-
case options::OPT__SLASH_MTd:
1175-
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib");
1176-
break;
1177-
case options::OPT__SLASH_MD:
1178-
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib");
1179-
break;
1180-
case options::OPT__SLASH_MDd:
1181-
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib");
1182-
break;
1183-
}
1184-
}
1181+
// 2.1. MSVC
1182+
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1183+
addFortranRuntimeLibsMSVC(Args, CmdArgs);
1184+
return;
11851185
}
1186+
1187+
// 2.2. GNU and similar
1188+
// The --whole-archive option needs to be part of the link line to make
1189+
// sure that the main() function from Fortran_main.a is pulled in by the
1190+
// linker. However, it shouldn't be used if it's already active.
1191+
// TODO: Find an equivalent of `--whole-archive` for Darwin.
1192+
if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX()) {
1193+
CmdArgs.push_back("--whole-archive");
1194+
CmdArgs.push_back("-lFortran_main");
1195+
CmdArgs.push_back("--no-whole-archive");
1196+
return;
1197+
}
1198+
1199+
CmdArgs.push_back("-lFortran_main");
11861200
}
11871201

11881202
void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,

flang/test/Driver/linker-flags.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,23 @@
2828
! executable and may find the GNU linker from MinGW or Cygwin.
2929
! UNIX-LABEL: "{{.*}}ld{{(\.exe)?}}"
3030
! UNIX-SAME: "[[object_file]]"
31-
! UNIX-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" "-lm"
31+
! UNIX-SAME: "-lFortranRuntime" "-lFortranDecimal" "--whole-archive" "-lFortran_main" "--no-whole-archive" "-lm"
3232

3333
! DARWIN-LABEL: "{{.*}}ld{{(\.exe)?}}"
3434
! DARWIN-SAME: "[[object_file]]"
35-
! DARWIN-SAME: -lFortran_main
3635
! DARWIN-SAME: -lFortranRuntime
3736
! DARWIN-SAME: -lFortranDecimal
37+
! DARWIN-SAME: -lFortran_main
3838

3939
! HAIKU-LABEL: "{{.*}}ld{{(\.exe)?}}"
4040
! HAIKU-SAME: "[[object_file]]"
41-
! HAIKU-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal"
41+
! HAIKU-SAME: "-lFortranRuntime" "-lFortranDecimal" "--whole-archive" "-lFortran_main" "--no-whole-archive"
4242

4343
! MINGW-LABEL: "{{.*}}ld{{(\.exe)?}}"
4444
! MINGW-SAME: "[[object_file]]"
45-
! MINGW-SAME: -lFortran_main
4645
! MINGW-SAME: -lFortranRuntime
4746
! MINGW-SAME: -lFortranDecimal
47+
! MINGW-SAME: -lFortran_main
4848

4949
! NOTE: This also matches lld-link (when CLANG_DEFAULT_LINKER=lld) and
5050
! any .exe suffix that is added when resolving to the full path of

0 commit comments

Comments
 (0)