Skip to content

Commit

Permalink
[flang] Add dependent-lib option to flang -fc1 on Windows (#72121)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DavidTruby committed Nov 15, 2023
1 parent b6f5178 commit 77ecb9a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 3 deletions.
8 changes: 5 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">>;
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Frontend/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions flang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 16 additions & 0 deletions flang/test/Driver/dependent-lib.f90
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions flang/test/Driver/driver-help.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 77ecb9a

Please sign in to comment.