llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-coff @llvm/pr-subscribers-flang-fir-hlfir Author: David Truby (DavidTruby) <details> <summary>Changes</summary> This patch changes the behaviour for flang to only create and link to a `main` entry point when the Fortran code has a program statement in it. This means that flang-new can be used to link even when the program is a mixed C/Fortran code with `main` present in C and no entry point present in Fortran. --- Patch is 30.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/89938.diff 23 Files Affected: - (modified) clang/include/clang/Driver/Options.td (-6) - (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+1-109) - (modified) clang/lib/Driver/ToolChains/Flang.cpp (-9) - (modified) flang/docs/FlangDriver.md (+3-29) - (modified) flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h (+2-1) - (added) flang/include/flang/Optimizer/Builder/Runtime/Main.h (+28) - (modified) flang/lib/Lower/Bridge.cpp (+4-1) - (modified) flang/lib/Optimizer/Builder/CMakeLists.txt (+1) - (modified) flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp (+3-4) - (added) flang/lib/Optimizer/Builder/Runtime/Main.cpp (+62) - (modified) flang/runtime/CMakeLists.txt (-1) - (removed) flang/runtime/FortranMain/CMakeLists.txt (-23) - (removed) flang/runtime/FortranMain/Fortran_main.c (-23) - (modified) flang/test/CMakeLists.txt (-1) - (modified) flang/test/Driver/driver-help-hidden.f90 (-1) - (modified) flang/test/Driver/driver-help.f90 (-1) - (modified) flang/test/Driver/dynamic-linker.f90 (-2) - (modified) flang/test/Driver/emit-mlir.f90 (+10) - (modified) flang/test/Driver/linker-flags.f90 (-8) - (modified) flang/test/Driver/msvc-dependent-lib-flags.f90 (-4) - (modified) flang/test/Driver/no-duplicate-main.f90 (-2) - (modified) flang/tools/flang-driver/CMakeLists.txt (-1) - (modified) lld/COFF/MinGW.cpp (-1) ``````````diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 922bda721dc780..4b852b297a6b99 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6582,12 +6582,6 @@ def J : JoinedOrSeparate<["-"], "J">, Group<gfortran_Group>, Alias<module_dir>; -let Visibility = [FlangOption] in { -def no_fortran_main : Flag<["-"], "fno-fortran-main">, - Visibility<[FlangOption]>, Group<f_Group>, - HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">; -} // let Visibility = [ FlangOption ] - //===----------------------------------------------------------------------===// // FC1 Options //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index b65b96db16bd79..fec11c7e716fdf 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1191,118 +1191,10 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, return true; } -/// Determines if --whole-archive is active in the list of arguments. -static bool isWholeArchivePresent(const ArgList &Args) { - bool WholeArchiveActive = false; - for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) { - if (Arg) { - for (StringRef ArgValue : Arg->getValues()) { - if (ArgValue == "--whole-archive") - WholeArchiveActive = true; - if (ArgValue == "--no-whole-archive") - WholeArchiveActive = false; - } - } - } - - 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) { - unsigned RTOptionID = options::OPT__SLASH_MT; - if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { - RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue()) - .Case("static", options::OPT__SLASH_MT) - .Case("static_dbg", options::OPT__SLASH_MTd) - .Case("dll", options::OPT__SLASH_MD) - .Case("dll_dbg", options::OPT__SLASH_MDd) - .Default(options::OPT__SLASH_MT); - } - switch (RTOptionID) { - case options::OPT__SLASH_MT: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib"); - break; - case options::OPT__SLASH_MTd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib"); - break; - case options::OPT__SLASH_MD: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib"); - break; - case options::OPT__SLASH_MDd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib"); - break; - } -} - -// 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); - return; - } - - // 2. GNU and similar - const Driver &D = TC.getDriver(); - const char *FortranMainLinkFlag = "-lFortran_main"; - - // Warn if the user added `-lFortran_main` - this library is an implementation - // detail of Flang and should be handled automaticaly by the driver. - for (const char *arg : CmdArgs) { - if (strncmp(arg, FortranMainLinkFlag, strlen(FortranMainLinkFlag)) == 0) - D.Diag(diag::warn_drv_deprecated_custom) - << FortranMainLinkFlag - << "see the Flang driver documentation for correct usage"; - } - - // The --whole-archive option needs to be part of the link line to make - // sure that the main() function from Fortran_main.a is pulled in by the - // linker. However, it shouldn't be used if it's already active. - // TODO: Find an equivalent of `--whole-archive` for Darwin and AIX. - if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() && - !TC.getTriple().isOSAIX()) { - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back(FortranMainLinkFlag); - CmdArgs.push_back("--no-whole-archive"); - return; - } - - CmdArgs.push_back(FortranMainLinkFlag); -} - /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { - // 1. Link FortranMain - // FortranMain depends on FortranRuntime, so needs to be listed first. If - // -fno-fortran-main has been passed, skip linking Fortran_main.a - if (!Args.hasArg(options::OPT_no_fortran_main)) - addFortranMain(TC, Args, CmdArgs); - - // 2. Link FortranRuntime and FortranDecimal + // Link FortranRuntime and FortranDecimal // These are handled earlier on Windows by telling the frontend driver to // add the correct libraries to link against as dependents in the object // file. diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 6d93c1f3d7034a..8955b9fb653c2a 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -282,7 +282,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, assert(TC.getTriple().isKnownWindowsMSVCEnvironment() && "can only add VS runtime library on Windows!"); // if -fno-fortran-main has been passed, skip linking Fortran_main.a - bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main); if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins"))); @@ -300,8 +299,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, case options::OPT__SLASH_MT: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("--dependent-lib=libcmt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib"); break; @@ -309,8 +306,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("--dependent-lib=libcmtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib"); break; @@ -318,8 +313,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib"); break; @@ -328,8 +321,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib"); break; diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md index ac120b4ff09b6d..351595ac0afdb7 100644 --- a/flang/docs/FlangDriver.md +++ b/flang/docs/FlangDriver.md @@ -179,46 +179,20 @@ like this: ``` $ flang -v -o example example.o -"/usr/bin/ld" [...] example.o [...] "--whole-archive" "-lFortran_main" -"--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" [...] +"/usr/bin/ld" [...] example.o [...] "-lFortranRuntime" "-lFortranDecimal" [...] ``` The automatically added libraries are: -* `Fortran_main`: Provides the main entry point `main` that then invokes - `_QQmain` with the Fortran program unit. This library has a dependency to - the `FortranRuntime` library. * `FortranRuntime`: Provides most of the Flang runtime library. * `FortranDecimal`: Provides operations for decimal numbers. -The default is that, when using Flang as the linker, one of the Fortran -translation units provides the program unit and therefore it is assumed that -Fortran is the main code part (calling into C/C++ routines via `BIND (C)` -interfaces). When composing the linker commandline, Flang uses -`--whole-archive` and `--no-whole-archive` (Windows: `/WHOLEARCHIVE:`, -Darwin & AIX: *not implemented yet*) to make sure that all for `Fortran_main` -is processed by the linker. This is done to issue a proper error message when -multiple definitions of `main` occur. This happens, for instance, when linking -a code that has a Fortran program unit with a C/C++ code that also defines a -`main` function. A user may be required to explicitly provide the C++ runtime -libraries at link time (e.g., via `-lstdc++` for STL) - If the code is C/C++ based and invokes Fortran routines, one can either use Clang or Flang as the linker driver. If Clang is used, it will automatically all required runtime libraries needed by C++ (e.g., for STL) to the linker invocation. In this case, one has to explicitly provide the Fortran runtime libraries -`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link -and use the `-fno-fortran-main` flag. This flag removes -`Fortran_main` from the linker stage and hence requires one of the C/C++ -translation units to provide a definition of the `main` function. In this case, -it may be required to explicitly supply C++ runtime libraries as mentioned above. - -When creating shared or static libraries using Flang with `-shared` or `-static` -flag, Fortran_main is automatically removed from the linker stage (i.e., -`-fno-fortran-main` is on by default). It is assumed that when creating a -static or shared library, the generated library does not need a `main` -function, as a final link stage will occur that will provide the `Fortran_main` -library when creating the final executable. +`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link. +In this case, it may be required to explicitly supply C++ runtime libraries. On Darwin, the logical root where the system libraries are located (sysroot) must be specified. This can be done with the CMake build flag `DEFAULT_SYSROOT` diff --git a/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h b/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h index 18a24bad396044..216d3bcec137e1 100755 --- a/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h @@ -22,6 +22,7 @@ namespace fir { class FirOpBuilder; +class GlobalOp; } // namespace fir namespace mlir { @@ -37,7 +38,7 @@ namespace fir::runtime { /// Create the list of environment variable defaults for the runtime to set. The /// form of the generated list is defined in the runtime header file /// environment-default-list.h -void genEnvironmentDefaults( +fir::GlobalOp genEnvironmentDefaults( fir::FirOpBuilder &builder, mlir::Location loc, const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults); diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Main.h b/flang/include/flang/Optimizer/Builder/Runtime/Main.h new file mode 100644 index 00000000000000..62faf46e1fc778 --- /dev/null +++ b/flang/include/flang/Optimizer/Builder/Runtime/Main.h @@ -0,0 +1,28 @@ +//===-- Main.h - generate main runtime API calls ----------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H +#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H + +namespace mlir { +class Location; +} // namespace mlir + +namespace fir { +class FirOpBuilder; +class GlobalOp; +} // namespace fir + +namespace fir::runtime { + +void genMain(fir::FirOpBuilder &builder, mlir::Location loc, + fir::GlobalOp &env); + +} + +#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 8b62fe8c022f80..afb5496ff8bc29 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -36,6 +36,7 @@ #include "flang/Optimizer/Builder/Runtime/Character.h" #include "flang/Optimizer/Builder/Runtime/Derived.h" #include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h" +#include "flang/Optimizer/Builder/Runtime/Main.h" #include "flang/Optimizer/Builder/Runtime/Ragged.h" #include "flang/Optimizer/Builder/Runtime/Stop.h" #include "flang/Optimizer/Builder/Todo.h" @@ -359,8 +360,10 @@ class FirConverter : public Fortran::lower::AbstractConverter { // not need to be generated even if no defaults are specified. // However, generating main or changing when the runtime reads // environment variables is required to do so. - fir::runtime::genEnvironmentDefaults(*builder, toLocation(), + auto env = fir::runtime::genEnvironmentDefaults(*builder, toLocation(), bridge.getEnvironmentDefaults()); + + fir::runtime::genMain(*builder, toLocation(), env); }); finalizeOpenACCLowering(); diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt index 06339b116cd899..95f19ed4dfbdf8 100644 --- a/flang/lib/Optimizer/Builder/CMakeLists.txt +++ b/flang/lib/Optimizer/Builder/CMakeLists.txt @@ -24,6 +24,7 @@ add_flang_library(FIRBuilder Runtime/Inquiry.cpp Runtime/Intrinsics.cpp Runtime/Numeric.cpp + Runtime/Main.cpp Runtime/Pointer.cpp Runtime/Ragged.cpp Runtime/Reduction.cpp diff --git a/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp b/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp index a11b9339681e3b..6e280ac0c06cd2 100755 --- a/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp @@ -13,7 +13,7 @@ #include "flang/Optimizer/Support/InternalNames.h" #include "llvm/ADT/ArrayRef.h" -void fir::runtime::genEnvironmentDefaults( +fir::GlobalOp fir::runtime::genEnvironmentDefaults( fir::FirOpBuilder &builder, mlir::Location loc, const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults) { std::string envDefaultListPtrName = @@ -34,14 +34,13 @@ void fir::runtime::genEnvironmentDefaults( // If no defaults were specified, initialize with a null pointer. if (envDefaults.empty()) { - builder.createGlobalConstant( + return builder.createGlobalConstant( loc, envDefaultListRefTy, envDefaultListPtrName, [&](fir::FirOpBuilder &builder) { mlir::Value nullVal = builder.createNullConstant(loc, envDefaultListRefTy); builder.create<fir::HasValueOp>(loc, nullVal); }); - return; } // Create the Item list. @@ -99,7 +98,7 @@ void fir::runtime::genEnvironmentDefaults( envDefaultListBuilder, linkOnce); // Define the pointer to the list used by the runtime. - builder.createGlobalConstant( + return builder.createGlobalConstant( loc, envDefaultListRefTy, envDefaultListPtrName, [&](fir::FirOpBuilder &builder) { mlir::Value addr = builder.create<fir::AddrOfOp>( diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp new file mode 100644 index 00000000000000..93d082b8094eb6 --- /dev/null +++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp @@ -0,0 +1,62 @@ +//===-- Main.cpp - generate main runtime API calls ----------------*- 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/Optimizer/Builder/Runtime/Main.h" +#include "flang/Optimizer/Builder/BoxValue.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Runtime/main.h" +#include "flang/Runtime/stop.h" + +using namespace Fortran::runtime; + +/// Create a `int main(...)` that calls the Fortran entry point +void fir::runtime::genMain(fir::FirOpBuilder &builder, mlir::Location loc, + fir::GlobalOp &env) { + auto *context = builder.getContext(); + auto argcTy = builder.getDefaultIntegerType(); + auto ptrTy = mlir::LLVM::LLVMPointerType::get(context); + + // void ProgramStart(int argc, char** argv, char** envp, _QQEnvironmentDefaults* env) + auto startFn = builder.createFunction( + loc, RTNAME_STRING(ProgramStart), + mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy, ptrTy}, {})); + // void ProgramStop() + auto stopFn = + builder.createFunction(loc, RTNAME_STRING(ProgramEndStatement), + mlir::FunctionType::get(context, {}, {})); + + // int main(int argc, char** argv, char** envp) + auto mainFn = builder.createFunction( + loc, "main", + mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy}, argcTy)); + // void _QQmain() + auto qqMainFn = builder.createFunction(loc, "_QQmain", + mlir::FunctionType::get(context, {}, {})); + + mainFn.setPublic(); + + auto *block = mainFn.addEntryBlock(); + mlir::OpBuilder::InsertionGuard insertGuard(builder); + builder.setInsertionPointToStart(block); + + llvm::SmallVector<mlir::Value, 4> args (block->getArguments()); + auto envAddr = + builder.create<fir::AddrOfOp>(loc, env.getType(), env.getSymbol()); + args.push_back(envAddr); + + builder.create<fir::CallOp>(loc, startFn, args); + builder.create<fir::CallOp>(loc, qqMainFn); + builder.create<fir::CallOp>(loc, stopFn); + + mlir::Value ret = builder.createIntegerConstant(loc, argcTy, 0); + builder.create<mlir::func::ReturnOp>(loc, ret); +} diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt index bdd0e07bbfd4d1..9f25c5dfcad11d 100644 --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -103,7 +103,6 @@ append(${NO_LTO_FLAGS} CMAKE_CXX_FLAGS) add_definitions(-U_GLIBCXX_ASSERTIONS) add_definitions(-U_LIBCPP_ENABLE_ASSERTIONS) -add_subdirectory(FortranMain) add_subdirectory(Float128Math) set(sources diff --git a/flang/runtime/FortranMain/CMakeLists.txt b/flang/runtime/FortranMain/CMakeLists.txt deleted file mode 100644 index deb7bd10acf512..00000000000000 --- a/flang/runtime/FortranMain/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_flang_library(Fortran_main STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c -) -if (DEFINED MSVC) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) - add_flang_library(Fortran_main.static STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c - ) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) - add_flang_library(Fortran_main.dynamic S... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/89938 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits