[flang] [clang] [flang][driver] Remove Fortain_main static library from linking stages (PR #75816)
Michael Klemm via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 18 07:48:47 PST 2023
https://github.com/mjklemm created https://github.com/llvm/llvm-project/pull/75816
At present, when building static or shared libraries, Flang adds `-lFortran_main.a` (or `/WHOLEARCHIVE:Fortran.*.lib` pon Windows) to the link line. This leads to the problem that `_QQmain` and `_QQEnvironmentDefaults` (as of the time of this PR) are symbols marked as used, while `main` is being defined. This should not happen and this PR fixes this by detecting if `-shared` or `-static` is used on the Flang command line and removing the static `Fortran_main` library.
>From 511f3a4537267284554bf6b33470a01d747b8a94 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Sat, 16 Dec 2023 20:15:17 +0100
Subject: [PATCH 1/2] Remove -lFortran_main from the link line when -shared is
present
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 45901ee7157f77..5d525d3794ad1d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1133,6 +1133,17 @@ static bool isWholeArchivePresent(const ArgList &Args) {
return WholeArchiveActive;
}
+static bool isSharedLinkage(const ArgList &Args) {
+ bool FoundSharedFlag = false;
+ for (auto *Arg : Args.filtered(options::OPT_shared)) {
+ if (Arg) {
+ FoundSharedFlag = true;
+ }
+ }
+
+ return FoundSharedFlag;
+}
+
/// Add Fortran runtime libs for MSVC
static void addFortranRuntimeLibsMSVC(const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
@@ -1164,6 +1175,17 @@ static void addFortranRuntimeLibsMSVC(const ArgList &Args,
// Add FortranMain runtime lib
static void addFortranMain(const ToolChain &TC, const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
+ // 0. Shared-library linkage
+ // If we are attempting to link a shared library, we should not add
+ // -lFortran_main.a to the link line, as the `main` symbol is not
+ // required for a shared library and should also be provided by one
+ // of the translation units of the code that this shared library
+ // will be linked against eventually.
+ if (isSharedLinkage(Args)) {
+ printf("MK: --> shared linkage, do not add -lFortranMain\n");
+ return;
+ }
+
// 1. MSVC
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
addFortranRuntimeLibsMSVC(Args, CmdArgs);
>From 930f2c447daa625d9e6019cd38d82b5750942f5d Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Mon, 18 Dec 2023 11:27:59 +0100
Subject: [PATCH 2/2] Update dynamic_linker.f90 test and clean up a bit
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 22 ++++++++++------------
flang/test/Driver/dynamic-linker.f90 | 8 ++++++--
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5d525d3794ad1d..05ebd42829c95d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1133,15 +1133,14 @@ static bool isWholeArchivePresent(const ArgList &Args) {
return WholeArchiveActive;
}
+/// Determine if driver is invoked to create a shared object library (-static)
static bool isSharedLinkage(const ArgList &Args) {
- bool FoundSharedFlag = false;
- for (auto *Arg : Args.filtered(options::OPT_shared)) {
- if (Arg) {
- FoundSharedFlag = true;
- }
- }
+ return Args.hasArg(options::OPT_shared);
+}
- return FoundSharedFlag;
+/// Determine if driver is invoked to create a static object library (-shared)
+static bool isStaticLinkage(const ArgList &Args) {
+ return Args.hasArg(options::OPT_static);
}
/// Add Fortran runtime libs for MSVC
@@ -1176,13 +1175,12 @@ static void addFortranRuntimeLibsMSVC(const ArgList &Args,
static void addFortranMain(const ToolChain &TC, const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
// 0. Shared-library linkage
- // If we are attempting to link a shared library, we should not add
+ // If we are attempting to link a library, we should not add
// -lFortran_main.a to the link line, as the `main` symbol is not
- // required for a shared library and should also be provided by one
- // of the translation units of the code that this shared library
+ // required for a library and should also be provided by one of
+ // the translation units of the code that this shared library
// will be linked against eventually.
- if (isSharedLinkage(Args)) {
- printf("MK: --> shared linkage, do not add -lFortranMain\n");
+ if (isSharedLinkage(Args) || isStaticLinkage(Args)) {
return;
}
diff --git a/flang/test/Driver/dynamic-linker.f90 b/flang/test/Driver/dynamic-linker.f90
index df119c22a2ea51..af07e2483f93fa 100644
--- a/flang/test/Driver/dynamic-linker.f90
+++ b/flang/test/Driver/dynamic-linker.f90
@@ -3,18 +3,22 @@
! RUN: %flang -### --target=x86_64-linux-gnu -rpath /path/to/dir -shared \
! RUN: -static %s 2>&1 | FileCheck \
-! RUN: --check-prefixes=GNU-LINKER-OPTIONS %s
+! RUN: --check-prefixes=GNU-LINKER-OPTIONS \
+! RUN: --implicit-check-not=GNU-LINKER-OPTIONS-NOT %s
! RUN: %flang -### --target=x86_64-windows-msvc -rpath /path/to/dir -shared \
! RUN: -static %s 2>&1 | FileCheck \
-! RUN: --check-prefixes=MSVC-LINKER-OPTIONS %s
+! RUN: --check-prefixes=MSVC-LINKER-OPTIONS \
+! RUN: --implicit-check-not=MSVC-LINKER-OPTIONS-NOT %s
! TODO: Could the linker have an extension or a suffix?
! GNU-LINKER-OPTIONS: "{{.*}}ld{{(.exe)?}}"
! GNU-LINKER-OPTIONS-SAME: "-shared"
! GNU-LINKER-OPTIONS-SAME: "-static"
! GNU-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir"
+! GNU-LINKER-OPTIONS-NOT: "-lFortran_main.a"
! For MSVC, adding -static does not add any additional linker options.
! MSVC-LINKER-OPTIONS: "{{.*}}link{{(.exe)?}}"
! MSVC-LINKER-OPTIONS-SAME: "-dll"
! MSVC-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir"
+! MSVC-LINKER-OPTIONS-NOT: "/WHOLEARCHIVE:Fortran_main"
More information about the cfe-commits
mailing list