-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][driver] Remove Fortain_main static library from linking stages #75816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-driver @llvm/pr-subscribers-clang Author: Michael Klemm (mjklemm) ChangesAt present, when building static or shared libraries, Flang adds Full diff: https://github.com/llvm/llvm-project/pull/75816.diff 2 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 45901ee7157f77..05ebd42829c95d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1133,6 +1133,16 @@ 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) {
+ return Args.hasArg(options::OPT_shared);
+}
+
+/// 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
static void addFortranRuntimeLibsMSVC(const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
@@ -1164,6 +1174,16 @@ 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 library, we should not add
+ // -lFortran_main.a to the link line, as the `main` symbol is not
+ // 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) || isStaticLinkage(Args)) {
+ return;
+ }
+
// 1. MSVC
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
addFortranRuntimeLibsMSVC(Args, CmdArgs);
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"
|
Thanks! Mostly looks good, but I have a question:
Sorry for being pedantic, but not sure I follow. Also, not sure what defines Btw, would you mind adding a note to the driver docs? |
Yes, that's correct. The
The
Sure, I was planning to do this for the previous PR already but got distracted. Can you point me to the right place to add this? Thanks! |
I need to correct myself: _QQEnvironmentDefaults is not a function that is called, but rather an external file-scope variable that creates that symbol. The symbol used to initialize that is |
Somewhere here: I would probably create a section on building executables and just mention that 3 runtime libs will be linked auto-magically. Unless somebody uses |
I've have written up a first draft. Please have a look and let me know what you think. |
@banach-space How did you draw the pictures in the MD file that I'm changing? If you have some sort of source file, I can try to add a nice chart to the explanation, I'm adding. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense, thank you! I really appreciate you fixing this 🙏🏻
@kiranchandramohan - could you also take a look?
Looks reasonable to me. I guess the environment settings that are there in the EnvironmentDefaults apply only when the main program is compiled with some flags. It would be good to check the options in EnvironmentDefaults and see that they are all applicable only when compiled for the main program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG. Thanks.
Co-authored-by: kkwli <[email protected]>
8ff6553
to
b29a7fd
Compare
Co-authored-by: kkwli <[email protected]>
Thanks for all the good suggestions! |
For anyone (like me) having to deal with correctly linking Fortran_main with flang 18+, it's worth noting that much of this got removed again in 8d53866. |
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, whilemain
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 staticFortran_main
library.