[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.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -70,6 +70,9 @@ public:
|
||||
/// 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
16
flang/test/Driver/dependent-lib.f90
Normal file
16
flang/test/Driver/dependent-lib.f90
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user