awarzynski created this revision.
awarzynski added reviewers: kiranchandramohan, clementval.
Herald added a subscriber: mgorny.
Herald added a reviewer: sscalpone.
Herald added projects: Flang, All.
awarzynski requested review of this revision.
Herald added subscribers: cfe-commits, jdoerfert.
Herald added a project: clang.

This patch adds 2 missing items required for `flang-new` to be able to
generate executables:

1. Extra linker flags to include Fortran runtime libraries.

2. The Fortran_main runtime library, which implements the main entry point into 
Fortran's PROGRAM.

With this change, you can generate an executable that will print `hello,
world!` as follows:

  $ cat hello.f90
  program hello
    write (*,*), "hello, world!"
  end program hello
  $ flang-new hello.f90
  ./a.out
  hello, world!

Note: Fortran_main was originally written by Peter Klausler, Jean Perier
and Steve Scalpone in the fir-dev` branch in [1].

[1] https://github.com/flang-compiler/f18-llvm-project

Co-authored-by: Peter Klausler <pklaus...@nvidia.com>
Co-authored-by: Jean Perier <jper...@nvidia.com>
Co-authored-by: Steve Scalpone <sscalp...@nvidia.com


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122008

Files:
  clang/lib/Driver/ToolChains/Gnu.cpp
  flang/include/flang/Runtime/stop.h
  flang/runtime/CMakeLists.txt
  flang/runtime/FortranMain/CMakeLists.txt
  flang/runtime/FortranMain/Fortran_main.c
  flang/test/CMakeLists.txt
  flang/test/Driver/linker-flags.f90

Index: flang/test/Driver/linker-flags.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/linker-flags.f90
@@ -0,0 +1,30 @@
+! Verify that the Fortran runtime libraries are present in the linker
+! invocation. These libraries are added on top of other standard runtime
+! libraries that the Clang driver will include.
+
+! NOTE: The additional linker flags tested here are currently specified in
+! clang/lib/Driver/Toolchains/Gnu.cpp. This makes the current implementation GNU
+! (Linux) specific. The following line will make sure that this test is skipped
+! on Windows. Ideally we should find a more robust way of testing this.
+! REQUIRES: shell
+! UNSUPPORTED: darwin, macos
+
+!------------
+! RUN COMMAND
+!------------
+! RUN: %flang -### --ld-path=/usr/bin/ld %S/Inputs/hello.f90 2>&1 | FileCheck %s
+
+!----------------
+! EXPECTED OUTPUT
+!----------------
+! Compiler invocation to generate the object file
+! CHECK-LABEL: {{.*}} "-emit-obj"
+! CHECK-SAME:  "-o" "[[object_file:.*]]" {{.*}}Inputs/hello.f90
+
+! Linker invocation to generate the executable
+! CHECK-LABEL:  "/usr/bin/ld"
+! CHECK-SAME: "[[object_file]]"
+! CHECK-SAME: -lFortran_main
+! CHECK-SAME: -lFortranRuntime
+! CHECK-SAME: -lFortranDecimal
+! CHECK-SAME: -lm
Index: flang/test/CMakeLists.txt
===================================================================
--- flang/test/CMakeLists.txt
+++ flang/test/CMakeLists.txt
@@ -47,6 +47,7 @@
 
 set(FLANG_TEST_DEPENDS
   flang-new llvm-config FileCheck count not module_files fir-opt tco bbc llvm-objdump
+  FortranRuntime Fortran_main FortranDecimal
 )
 
 if (FLANG_INCLUDE_TESTS)
Index: flang/runtime/FortranMain/Fortran_main.c
===================================================================
--- /dev/null
+++ flang/runtime/FortranMain/Fortran_main.c
@@ -0,0 +1,22 @@
+//===-- runtime/FortranMain/Fortran_main.c --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Runtime/main.h"
+#include "flang/Runtime/stop.h"
+
+/* main entry into PROGRAM */
+void _QQmain();
+
+/* C main stub */
+int main(int argc, const char *argv[], const char *envp[])
+{
+  RTNAME(ProgramStart)(argc, argv, envp);
+  _QQmain();
+  RTNAME(ProgramEndStatement)();
+  return 0;
+}
Index: flang/runtime/FortranMain/CMakeLists.txt
===================================================================
--- /dev/null
+++ flang/runtime/FortranMain/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_flang_library(Fortran_main STATIC
+  Fortran_main.c
+)
Index: flang/runtime/CMakeLists.txt
===================================================================
--- flang/runtime/CMakeLists.txt
+++ flang/runtime/CMakeLists.txt
@@ -30,6 +30,8 @@
 # with different names
 include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR})
 
+add_subdirectory(FortranMain)
+
 add_flang_library(FortranRuntime
   ISO_Fortran_binding.cpp
   allocatable.cpp
Index: flang/include/flang/Runtime/stop.h
===================================================================
--- flang/include/flang/Runtime/stop.h
+++ flang/include/flang/Runtime/stop.h
@@ -27,7 +27,7 @@
 NORETURN void RTNAME(ProgramEndStatement)(NO_ARGUMENTS);
 
 // Extensions
-NORETURN void RTNAME(Exit)(int status = EXIT_SUCCESS);
+NORETURN void RTNAME(Exit)(int status DEFAULT_VALUE(EXIT_SUCCESS));
 NORETURN void RTNAME(Abort)(NO_ARGUMENTS);
 
 // Crash with an error message when the program dynamically violates a Fortran
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -379,6 +379,13 @@
                                          Exec, CmdArgs, Inputs, Output));
 }
 
+static void addFortranLinkerFlags(ArgStringList &CmdArgs) {
+  CmdArgs.push_back("-lFortran_main");
+  CmdArgs.push_back("-lFortranRuntime");
+  CmdArgs.push_back("-lFortranDecimal");
+  CmdArgs.push_back("-lm");
+}
+
 void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                            const InputInfo &Output,
                                            const InputInfoList &Inputs,
@@ -665,6 +672,10 @@
     }
   }
 
+  // Additional linker flags for Fortran
+  if (D.IsFlangMode())
+    addFortranLinkerFlags(CmdArgs);
+
   Args.AddAllArgs(CmdArgs, options::OPT_T);
 
   const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to