Skip to content

Commit 8c28768

Browse files
committed
[Driver] Pass Classic Flang libraries to the linker correctly
In LLVM 15, the Fortran and OpenMP runtime libraries are added to the linker command line using common methods (addFortranRuntime* and addOpenMPRuntime*). This commit adds Classic Flang awareness to addFortranRuntime*, so that Classic Flang doesn't attempt to link with LLVM Flang libraries. Re-using the same methods as Clang and LLVM Flang also helps reduce downstream delta. A Classic Flang test is added to ensure that the linker command is constructed correctly. LLVM 19 porting note: This commit has been amended to add back the -fno-fortran-main option that was deleted in upstream commit 8d53866.
1 parent 8f38f29 commit 8c28768

File tree

6 files changed

+72
-49
lines changed

6 files changed

+72
-49
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6776,6 +6776,12 @@ def fhermetic_module_files : Flag<["-"], "fhermetic-module-files">, Group<f_Grou
67766776
def J : JoinedOrSeparate<["-"], "J">,
67776777
Flags<[RenderJoined]>,
67786778
Group<gfortran_Group>;
6779+
6780+
let Visibility = [FlangOption] in {
6781+
def no_fortran_main : Flag<["-"], "fno-fortran-main">,
6782+
Visibility<[FlangOption]>, Group<f_Group>,
6783+
HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">;
6784+
} // let Visibility = [ FlangOption ]
67796785
#else
67806786
def J : JoinedOrSeparate<["-"], "J">,
67816787
Flags<[RenderJoined]>, Visibility<[FlangOption, FC1Option]>,

clang/lib/Driver/ToolChain.cpp

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,42 +1325,26 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,
13251325

13261326
#ifdef ENABLE_CLASSIC_FLANG
13271327
void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args,
1328-
ArgStringList &CmdArgs) const {
1329-
bool staticFlangLibs = false;
1330-
bool useOpenMP = false;
1331-
1328+
ArgStringList &CmdArgs) const {
1329+
bool StaticFlangLibs = false;
13321330
if (Args.hasArg(options::OPT_staticFlangLibs)) {
1333-
for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) {
1334-
A->claim();
1335-
staticFlangLibs = true;
1336-
}
1337-
}
1338-
1339-
Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp,
1340-
options::OPT_fopenmp, options::OPT_fno_openmp);
1341-
if (A &&
1342-
(A->getOption().matches(options::OPT_mp) ||
1343-
A->getOption().matches(options::OPT_fopenmp))) {
1344-
useOpenMP = true;
1331+
StaticFlangLibs = true;
1332+
Args.ClaimAllArgs(options::OPT_staticFlangLibs);
13451333
}
13461334

1347-
if (staticFlangLibs)
1335+
if (StaticFlangLibs && !Args.hasArg(options::OPT_static))
13481336
CmdArgs.push_back("-Bstatic");
13491337
CmdArgs.push_back("-lflang");
13501338
CmdArgs.push_back("-lflangrti");
13511339
CmdArgs.push_back("-lpgmath");
1352-
if (useOpenMP)
1353-
CmdArgs.push_back("-lomp");
1354-
if (staticFlangLibs)
1340+
if (StaticFlangLibs && !Args.hasArg(options::OPT_static))
13551341
CmdArgs.push_back("-Bdynamic");
13561342

1357-
CmdArgs.push_back("-lm");
1343+
// Always link Fortran executables with pthreads.
1344+
CmdArgs.push_back("-lpthread");
13581345

13591346
if (!Triple.isOSDarwin())
13601347
CmdArgs.push_back("-lrt");
1361-
1362-
// Allways link Fortran executables with Pthreads
1363-
CmdArgs.push_back("-lpthread");
13641348
}
13651349
#endif
13661350

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,11 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
12731273
bool ForceStaticHostRuntime, bool IsOffloadingHost,
12741274
bool GompNeedsRT) {
12751275
if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1276-
options::OPT_fno_openmp, false))
1276+
options::OPT_fno_openmp, false)
1277+
#ifdef ENABLE_CLASSIC_FLANG
1278+
&& !Args.hasFlag(options::OPT_mp, options::OPT_nomp, false)
1279+
#endif
1280+
)
12771281
return false;
12781282

12791283
Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args);
@@ -1323,6 +1327,12 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
13231327
/// Add Fortran runtime libs
13241328
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
13251329
llvm::opt::ArgStringList &CmdArgs) {
1330+
#ifdef ENABLE_CLASSIC_FLANG
1331+
if (needFortranLibs(TC.getDriver(), Args))
1332+
TC.AddFortranStdlibLibArgs(Args, CmdArgs);
1333+
else
1334+
Args.ClaimAllArgs(options::OPT_noFlangLibs);
1335+
#else
13261336
// Link FortranRuntime and FortranDecimal
13271337
// These are handled earlier on Windows by telling the frontend driver to
13281338
// add the correct libraries to link against as dependents in the object
@@ -1342,6 +1352,7 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
13421352
CmdArgs.push_back("-lFortranRuntime");
13431353
CmdArgs.push_back("-lFortranDecimal");
13441354
}
1355+
#endif
13451356
}
13461357

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

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -721,18 +721,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
721721
if (getToolChain().ShouldLinkCXXStdlib(Args))
722722
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
723723

724-
#ifdef ENABLE_CLASSIC_FLANG
725-
// Add Fortran runtime libraries
726-
if (needFortranLibs(getToolChain().getDriver(), Args)) {
727-
getToolChain().AddFortranStdlibLibArgs(Args, CmdArgs);
728-
} else {
729-
// Claim "no Flang libraries" arguments if any
730-
for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) {
731-
Arg->claim();
732-
}
733-
}
734-
#endif
735-
736724
bool NoStdOrDefaultLibs =
737725
Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
738726
bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib);

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -550,18 +550,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
550550
// The profile runtime also needs access to system libraries.
551551
getToolChain().addProfileRTLibs(Args, CmdArgs);
552552

553-
#ifdef ENABLE_CLASSIC_FLANG
554-
// Add Fortran runtime libraries
555-
if (needFortranLibs(D, Args)) {
556-
ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs);
557-
} else {
558-
// Claim "no Flang libraries" arguments if any
559-
for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) {
560-
Arg->claim();
561-
}
562-
}
563-
#endif
564-
565553
if (D.CCCIsCXX() &&
566554
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
567555
options::OPT_r)) {

clang/test/Driver/flang/classic-flang.f95

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,49 @@
4141
! CHECK-ASM-SAME: "-o" "classic-flang.s"
4242
! CHECK-ASM-SAME: "-x" "ir"
4343
! CHECK-ASM-SAME: [[LLFILE]]
44+
45+
! Check that the linker job is given the correct libraries and library paths.
46+
47+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp \
48+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s
49+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp -nomp \
50+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s
51+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp \
52+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s
53+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -fno-openmp \
54+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s
55+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-openmp \
56+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-STATIC-OMP %s
57+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-flang-libs \
58+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-FLANG,CHECK-DYNAMIC-OMP %s
59+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static-flang-libs \
60+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-FLANG,CHECK-NO-OMP %s
61+
62+
! CHECK-LD: "{{.*}}ld"
63+
! CHECK-LD-NOT: "-static"
64+
! CHECK-LD: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*}}/basic_linux_tree/usr/lib"
65+
! CHECK-DYNAMIC-FLANG-NOT: "-Bstatic"
66+
! CHECK-DYNAMIC-FLANG: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm"
67+
! CHECK-DYNAMIC-FLANG-NOT: "-Bdynamic"
68+
! CHECK-STATIC-FLANG: "-Bstatic" "-lflang" "-lflangrti" "-lpgmath" "-Bdynamic" "-lpthread" "-lrt" "-lm"
69+
! CHECK-DYNAMIC-OMP-NOT: "-Bstatic"
70+
! CHECK-DYNAMIC-OMP: "-lomp" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib"
71+
! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic"
72+
! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib"
73+
! CHECK-NO-OMP-NOT: "-lomp"
74+
75+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -static-flang-libs \
76+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-NO-OMP %s
77+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp \
78+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s
79+
! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp -static-openmp \
80+
! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s
81+
! CHECK-LD-STATIC: "{{.*}}ld"
82+
! CHECK-LD-STATIC: "-static" "-o" "a.out"
83+
! CHECK-LD-STATIC: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*}}/basic_linux_tree/usr/lib"
84+
! CHECK-LD-STATIC-NOT: "-Bstatic"
85+
! CHECK-LD-STATIC: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm"
86+
! CHECK-LD-STATIC-NOT: "-Bdynamic"
87+
! CHECK-STATIC-BOTH-NOT: "-Bstatic"
88+
! CHECK-STATIC-BOTH: "-lomp"
89+
! CHECK-STATIC-BOTH-NOT: "-Bdynamic"

0 commit comments

Comments
 (0)