Author: David Truby Date: 2023-11-15T15:26:43Z New Revision: 77ecb9a49bb1640684c37f80ffe56bc54dae6502
URL: https://github.com/llvm/llvm-project/commit/77ecb9a49bb1640684c37f80ffe56bc54dae6502 DIFF: https://github.com/llvm/llvm-project/commit/77ecb9a49bb1640684c37f80ffe56bc54dae6502.diff LOG: [flang] Add dependent-lib option to flang -fc1 on Windows (#72121) This patch adds a --dependent-lib option to flang -fc1 on Windows to embed library link options into the object file. This is needed to properly select the Windows CRT to link against. Added: flang/test/Driver/dependent-lib.f90 Modified: clang/include/clang/Driver/Options.td flang/include/flang/Frontend/CodeGenOptions.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/test/Driver/driver-help.f90 Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e63ee583f6b30c5..b9694f5662c7b07 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6796,9 +6796,6 @@ def vectorize_loops : Flag<["-"], "vectorize-loops">, def vectorize_slp : Flag<["-"], "vectorize-slp">, HelpText<"Run the SLP vectorization passes">, MarshallingInfoFlag<CodeGenOpts<"VectorizeSLP">>; -def dependent_lib : Joined<["--"], "dependent-lib=">, - HelpText<"Add dependent library">, - MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>; def linker_option : Joined<["--"], "linker-option=">, HelpText<"Add linker option">, MarshallingInfoStringVector<CodeGenOpts<"LinkerOptions">>; @@ -7369,6 +7366,11 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">, HelpText<"File is for a position independent executable">, MarshallingInfoFlag<LangOpts<"PIE">>; + +def dependent_lib : Joined<["--"], "dependent-lib=">, + HelpText<"Add dependent library">, + MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>; + } // let Visibility = [CC1Option, FC1Option] let Visibility = [CC1Option] in { diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index a3c39bda10667be..b86bb88610a9a4a 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -70,6 +70,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The format used for serializing remarks (default: YAML) std::string OptRecordFormat; + /// Options to add to the linker for the object file + std::vector<std::string> DependentLibs; + // The RemarkKind enum class and OptRemark struct are identical to what Clang // has // TODO: Share with clang instead of re-implementing here diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 334da3ac287e3bf..cb4f2d6a6225205 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1054,6 +1054,27 @@ static bool parseVScaleArgs(CompilerInvocation &invoc, llvm::opt::ArgList &args, return true; } +static bool parseLinkerOptionsArgs(CompilerInvocation &invoc, + llvm::opt::ArgList &args, + clang::DiagnosticsEngine &diags) { + llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple); + + // TODO: support --dependent-lib on other platforms when MLIR supports + // !llvm.dependent.lib + if (args.hasArg(clang::driver::options::OPT_dependent_lib) && + !triple.isOSWindows()) { + const unsigned diagID = + diags.getCustomDiagID(clang::DiagnosticsEngine::Error, + "--dependent-lib is only supported on Windows"); + diags.Report(diagID); + return false; + } + + invoc.getCodeGenOpts().DependentLibs = + args.getAllArgValues(clang::driver::options::OPT_dependent_lib); + return true; +} + bool CompilerInvocation::createFromArgs( CompilerInvocation &res, llvm::ArrayRef<const char *> commandLineArgs, clang::DiagnosticsEngine &diags, const char *argv0) { @@ -1163,6 +1184,8 @@ bool CompilerInvocation::createFromArgs( success &= parseVScaleArgs(res, args, diags); + success &= parseLinkerOptionsArgs(res, args, diags); + // Set the string to be used as the return value of the COMPILER_OPTIONS // intrinsic of iso_fortran_env. This is either passed in from the parent // compiler driver invocation with an environment variable, or failing that diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 187bc52fa7063ef..54f2f37b1ac7424 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -203,6 +203,26 @@ static void setMLIRDataLayout(mlir::ModuleOp &mlirModule, mlirModule->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec); } +static void addDepdendentLibs(mlir::ModuleOp &mlirModule, + CompilerInstance &ci) { + const std::vector<std::string> &libs = + ci.getInvocation().getCodeGenOpts().DependentLibs; + if (libs.empty()) { + return; + } + // dependent-lib is currently only supported on Windows, so the list should be + // empty on non-Windows platforms + assert( + llvm::Triple(ci.getInvocation().getTargetOpts().triple).isOSWindows() && + "--dependent-lib is only supported on Windows"); + // Add linker options specified by --dependent-lib + auto builder = mlir::OpBuilder(mlirModule.getRegion()); + for (const std::string &lib : libs) { + builder.create<mlir::LLVM::LinkerOptionsOp>( + mlirModule.getLoc(), builder.getStrArrayAttr({"/DEFAULTLIB:", lib})); + } +} + bool CodeGenAction::beginSourceFileAction() { llvmCtx = std::make_unique<llvm::LLVMContext>(); CompilerInstance &ci = this->getInstance(); @@ -304,6 +324,9 @@ bool CodeGenAction::beginSourceFileAction() { Fortran::parser::Program &parseTree{*ci.getParsing().parseTree()}; lb.lower(parseTree, ci.getInvocation().getSemanticsContext()); + // Add dependent libraries + addDepdendentLibs(*mlirModule, ci); + // run the default passes. mlir::PassManager pm((*mlirModule)->getName(), mlir::OpPassManager::Nesting::Implicit); diff --git a/flang/test/Driver/dependent-lib.f90 b/flang/test/Driver/dependent-lib.f90 new file mode 100644 index 000000000000000..39c94c68c2484ab --- /dev/null +++ b/flang/test/Driver/dependent-lib.f90 @@ -0,0 +1,16 @@ +! REQUIRES aarch64-registered-target && x86-registered-target +! DEFINE: %{triple} = +! DEFINE: %{compile} = %flang_fc1 -emit-mlir -triple %{triple} --dependent-lib=libtest %s -o - 2>&1 +! REDEFINE: %{triple} = aarch64-pc-windows-msvc +! RUN: %{compile} | FileCheck %s +! REDEFINE: %{triple} = x86_64-pc-windows-msvc +! RUN: %{compile} | FileCheck %s +! REDEFINE: %{triple} = x86_64-linux-unknown-gnu +! RUN: not %{compile} | FileCheck %s --check-prefixes=CHECK-NOWIN +! REDEFINE: %{triple} = aarch64-apple-darwin +! RUN: not %{compile} | FileCheck %s --check-prefixes=CHECK-NOWIN + +! CHECK: llvm.linker_options ["/DEFAULTLIB:", "libtest"] +program test +end program test +! CHECK-NOWIN: --dependent-lib is only supported on Windows diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index ea9c892bd621058..452c62541e72e61 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -141,6 +141,7 @@ ! HELP-FC1-EMPTY: ! HELP-FC1-NEXT:OPTIONS: ! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros +! HELP-FC1-NEXT: --dependent-lib=<value> Add dependent library ! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted) ! HELP-FC1-NEXT: -emit-fir Build the parse tree, then lower it to FIR ! HELP-FC1-NEXT: -emit-hlfir Build the parse tree, then lower it to HLFIR _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits