Skip to content

Commit 76041a4

Browse files
authored
[flang][nfc] Refactor linker invocation logic (#75648)
Refactor how the Fortran runtime libs are added to the linker invocation. This is a non-functional change. This is an updated version of #75534. This iteration makes sure that FortranMain.a comes before FortranRuntme.a (the former depends on the latter).
1 parent c59ea32 commit 76041a4

File tree

1 file changed

+82
-63
lines changed

1 file changed

+82
-63
lines changed

clang/lib/Driver/ToolChains/CommonArgs.cpp

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

1119-
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
1120-
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);
1126-
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-
}
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;
11441129
}
1130+
}
1131+
}
11451132

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-
}
1133+
return WholeArchiveActive;
1134+
}
11541135

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-
}
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 FortranMain runtime lib
1165+
static void addFortranMain(const ToolChain &TC, const ArgList &Args,
1166+
llvm::opt::ArgStringList &CmdArgs) {
1167+
// 1. MSVC
1168+
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1169+
addFortranRuntimeLibsMSVC(Args, CmdArgs);
1170+
return;
1171+
}
1172+
1173+
// 2. GNU and similar
1174+
// The --whole-archive option needs to be part of the link line to make
1175+
// sure that the main() function from Fortran_main.a is pulled in by the
1176+
// linker. However, it shouldn't be used if it's already active.
1177+
// TODO: Find an equivalent of `--whole-archive` for Darwin.
1178+
if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX()) {
1179+
CmdArgs.push_back("--whole-archive");
1180+
CmdArgs.push_back("-lFortran_main");
1181+
CmdArgs.push_back("--no-whole-archive");
1182+
return;
1183+
}
1184+
1185+
CmdArgs.push_back("-lFortran_main");
1186+
}
1187+
1188+
/// Add Fortran runtime libs
1189+
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
1190+
llvm::opt::ArgStringList &CmdArgs) {
1191+
// 1. Link FortranMain
1192+
// FortranMain depends on FortranRuntime, so needs to be listed first. If
1193+
// -fno-fortran-main has been passed, skip linking Fortran_main.a
1194+
if (!Args.hasArg(options::OPT_no_fortran_main))
1195+
addFortranMain(TC, Args, CmdArgs);
1196+
1197+
// 2. Link FortranRuntime and FortranDecimal
1198+
// These are handled earlier on Windows by telling the frontend driver to
1199+
// add the correct libraries to link against as dependents in the object
1200+
// file.
1201+
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1202+
CmdArgs.push_back("-lFortranRuntime");
1203+
CmdArgs.push_back("-lFortranDecimal");
11851204
}
11861205
}
11871206

0 commit comments

Comments
 (0)