ekieri updated this revision to Diff 463998.
ekieri added a comment.

Fix test link-f90-main.f90, which was failing for statically linked builds.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134821/new/

https://reviews.llvm.org/D134821

Files:
  clang/lib/Driver/ToolChains/Gnu.cpp
  flang/docs/FlangDriver.md
  flang/test/CMakeLists.txt
  flang/test/Driver/link-c-main.c
  flang/test/Driver/link-f90-main.f90
  flang/test/Driver/linker-flags.f90

Index: flang/test/Driver/linker-flags.f90
===================================================================
--- flang/test/Driver/linker-flags.f90
+++ flang/test/Driver/linker-flags.f90
@@ -12,6 +12,9 @@
 !       Make sure they're not added.
 ! RUN: %flang -### -flang-experimental-exec -target aarch64-windows-msvc %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not libcmt --implicit-check-not oldnames
 
+! Check linker invocation to generate shared object (only GNU toolchain for now)
+! RUN: %flang -### -flang-experimental-exec -shared -target x86_64-linux-gnu %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,GNUSO --implicit-check-not _QQmain
+
 ! Compiler invocation to generate the object file
 ! CHECK-LABEL: {{.*}} "-emit-obj"
 ! CHECK-SAME:  "-o" "[[object_file:.*\.o]]" {{.*}}Inputs/hello.f90
@@ -19,6 +22,7 @@
 ! Linker invocation to generate the executable
 ! GNU-LABEL:  "{{.*}}ld" 
 ! GNU-SAME: "[[object_file]]"
+! GNU-SAME: --undefined=_QQmain
 ! GNU-SAME: -lFortran_main
 ! GNU-SAME: -lFortranRuntime
 ! GNU-SAME: -lFortranDecimal
@@ -46,3 +50,9 @@
 ! MSVC-SAME: FortranDecimal.lib
 ! MSVC-SAME: /subsystem:console
 ! MSVC-SAME: "[[object_file]]"
+
+! Linker invocation to generate a shared object
+! GNUSO-LABEL:  "{{.*}}ld"
+! GNUSO-SAME: "[[object_file]]"
+! GNUSO-SAME: -lFortranRuntime
+! GNUSO-SAME: -lFortranDecimal
Index: flang/test/Driver/link-f90-main.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/link-f90-main.f90
@@ -0,0 +1,22 @@
+! Test that a fortran main program can be linked to an executable
+! by flang.
+!
+! For now, this test only covers the Gnu toolchain on linux.
+
+! REQUIRES: x86-registered-target, system-linux
+
+! RUN: %flang_fc1 -emit-obj %s -o %t.o
+! RUN: %flang -target x86_64-unknown-linux-gnu %t.o -o %t.out -flang-experimental-exec
+! RUN: llvm-objdump --syms %t.out | FileCheck %s
+
+! Test that it also works if the program is bundled in an archive.
+
+! RUN: llvm-ar -r %t.a %t.o
+! RUN: %flang -target x86_64-unknown-linux-gnu %t.a -o %ta.out -flang-experimental-exec
+! RUN: llvm-objdump --syms %ta.out | FileCheck %s
+
+end program
+
+! CHECK-DAG: F .text {{[a-f0-9]+}} main
+! CHECK-DAG: F .text {{[a-f0-9]+}} _QQmain
+! CHECK-DAG: _FortranAProgramStart
Index: flang/test/Driver/link-c-main.c
===================================================================
--- /dev/null
+++ flang/test/Driver/link-c-main.c
@@ -0,0 +1,27 @@
+/*
+Test that an object file with a c main function can be linked to an executable
+by flang.
+
+For now, this test only covers the Gnu toolchain on linux.
+
+REQUIRES: x86-registered-target, system-linux, c-compiler
+
+RUN: %cc -c %s -o %t.o
+RUN: %flang -target x86_64-unknown-linux-gnu %t.o -o %t.out -flang-experimental-exec
+RUN: llvm-objdump --syms %t.out | FileCheck %s --implicit-check-not Fortran
+
+Test that it also works if the c-main is bundled in an archive.
+
+RUN: llvm-ar -r %t.a %t.o
+RUN: %flang -target x86_64-unknown-linux-gnu %t.a -o %ta.out -flang-experimental-exec
+RUN: llvm-objdump --syms %ta.out | FileCheck %s --implicit-check-not Fortran
+*/
+
+int main(void) {
+    return 0;
+}
+
+/*
+CHECK-DAG: F .text {{[a-f0-9]+}} main
+CHECK-DAG: *UND* {{[a-f0-9]+}} _QQmain
+*/
Index: flang/test/CMakeLists.txt
===================================================================
--- flang/test/CMakeLists.txt
+++ flang/test/CMakeLists.txt
@@ -55,6 +55,7 @@
   fir-opt
   tco
   bbc
+  llvm-ar
   llvm-dis
   llvm-objdump
   split-file
Index: flang/docs/FlangDriver.md
===================================================================
--- flang/docs/FlangDriver.md
+++ flang/docs/FlangDriver.md
@@ -149,13 +149,6 @@
 +- 3: backend, {2}, assembler
 4: assembler, {3}, object
 ```
-Note that currently Flang does not support code-generation and `flang-new` will
-fail during the second step above with the following error:
-```bash
-error: code-generation is not available yet
-```
-The other phases are printed nonetheless when using `-ccc-print-phases`, as
-that reflects what `clangDriver`, the library, will try to create and run.
 
 For actions specific to the frontend (e.g. preprocessing or code generation), a
 command to call the frontend driver is generated (more specifically, an
@@ -205,6 +198,40 @@
 words, `flang-new -fc1 <input-file>` is equivalent to `flang-new -fc1 -fsyntax-only
 <input-file>`.
 
+## Linker invocation
+Note: Linker invocation through the flang-new driver is so far
+experimental. This section describes the currently intended design, and not
+necessarily what is implemented.
+
+Calling
+```bash
+flang-new prog.f90
+```
+will, on a high level, do two things:
+* call the frontend driver to build the object file prog.o, and
+* call the system linker to build the executable a.out.
+
+In both invocations, flang-new will add default options. To see the exact
+invocations on your system, you can call
+```bash
+flang-new -### prog.f90
+```
+The link line will contain a fair number of options, which will depend on your
+system. Compared to when linking a c program with clang, the main additions are
+(on GNU/linux),
+* `--undefined=_QQmain`: A fortran main program will appear in the corresponding
+  object file as a function called `_QQmain`. This flag lets an object file
+  containing a fortran main program (i.e., a symbol `_QQmain`) be included in
+  the linking also when it is bundled in an archive.
+* `-lFortran_main`: The Fortran_main archive is part of flang's runtime. It
+  exports the symbol `main`, i.e., a c main function, which will make some
+  initial configuration before calling `_QQmain`, and clean up before returning.
+* `-lFortranRuntime`: Flang's fortran runtime, containing, for example,
+  implementations of intrinsic functions.
+* `-lFortranDecimal`: Part of flang's runtime, containing routines for parsing
+  and formatting decimal numbers.
+* `-lm`: Link with the math library, on which flang's runtime depends.
+
 ## The `flang-to-external-fc` script
 The `flang-to-external-fc` wrapper script for `flang-new` was introduced as a
 development tool and to facilitate testing. The `flang-to-external-fc` wrapper
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -601,6 +601,12 @@
   // these dependencies need to be listed before the C runtime below (i.e.
   // AddRuntTimeLibs).
   if (D.IsFlangMode()) {
+    // A Fortran main program will be lowered to a function named _QQmain. Make
+    // _QQmain an undefined symbol, so that we include it even if it hides
+    // inside an archive.
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("--undefined=_QQmain");
+
     addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
     addFortranRuntimeLibs(ToolChain, CmdArgs);
     CmdArgs.push_back("-lm");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to