Skip to content

Commit 77ecb9a

Browse files
authored
[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.
1 parent b6f5178 commit 77ecb9a

File tree

6 files changed

+71
-3
lines changed

6 files changed

+71
-3
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6796,9 +6796,6 @@ def vectorize_loops : Flag<["-"], "vectorize-loops">,
67966796
def vectorize_slp : Flag<["-"], "vectorize-slp">,
67976797
HelpText<"Run the SLP vectorization passes">,
67986798
MarshallingInfoFlag<CodeGenOpts<"VectorizeSLP">>;
6799-
def dependent_lib : Joined<["--"], "dependent-lib=">,
6800-
HelpText<"Add dependent library">,
6801-
MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>;
68026799
def linker_option : Joined<["--"], "linker-option=">,
68036800
HelpText<"Add linker option">,
68046801
MarshallingInfoStringVector<CodeGenOpts<"LinkerOptions">>;
@@ -7369,6 +7366,11 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
73697366
HelpText<"File is for a position independent executable">,
73707367
MarshallingInfoFlag<LangOpts<"PIE">>;
73717368

7369+
7370+
def dependent_lib : Joined<["--"], "dependent-lib=">,
7371+
HelpText<"Add dependent library">,
7372+
MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>;
7373+
73727374
} // let Visibility = [CC1Option, FC1Option]
73737375

73747376
let Visibility = [CC1Option] in {

flang/include/flang/Frontend/CodeGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
7070
/// The format used for serializing remarks (default: YAML)
7171
std::string OptRecordFormat;
7272

73+
/// Options to add to the linker for the object file
74+
std::vector<std::string> DependentLibs;
75+
7376
// The RemarkKind enum class and OptRemark struct are identical to what Clang
7477
// has
7578
// TODO: Share with clang instead of re-implementing here

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,27 @@ static bool parseVScaleArgs(CompilerInvocation &invoc, llvm::opt::ArgList &args,
10541054
return true;
10551055
}
10561056

1057+
static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
1058+
llvm::opt::ArgList &args,
1059+
clang::DiagnosticsEngine &diags) {
1060+
llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple);
1061+
1062+
// TODO: support --dependent-lib on other platforms when MLIR supports
1063+
// !llvm.dependent.lib
1064+
if (args.hasArg(clang::driver::options::OPT_dependent_lib) &&
1065+
!triple.isOSWindows()) {
1066+
const unsigned diagID =
1067+
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
1068+
"--dependent-lib is only supported on Windows");
1069+
diags.Report(diagID);
1070+
return false;
1071+
}
1072+
1073+
invoc.getCodeGenOpts().DependentLibs =
1074+
args.getAllArgValues(clang::driver::options::OPT_dependent_lib);
1075+
return true;
1076+
}
1077+
10571078
bool CompilerInvocation::createFromArgs(
10581079
CompilerInvocation &res, llvm::ArrayRef<const char *> commandLineArgs,
10591080
clang::DiagnosticsEngine &diags, const char *argv0) {
@@ -1163,6 +1184,8 @@ bool CompilerInvocation::createFromArgs(
11631184

11641185
success &= parseVScaleArgs(res, args, diags);
11651186

1187+
success &= parseLinkerOptionsArgs(res, args, diags);
1188+
11661189
// Set the string to be used as the return value of the COMPILER_OPTIONS
11671190
// intrinsic of iso_fortran_env. This is either passed in from the parent
11681191
// compiler driver invocation with an environment variable, or failing that

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,26 @@ static void setMLIRDataLayout(mlir::ModuleOp &mlirModule,
203203
mlirModule->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);
204204
}
205205

206+
static void addDepdendentLibs(mlir::ModuleOp &mlirModule,
207+
CompilerInstance &ci) {
208+
const std::vector<std::string> &libs =
209+
ci.getInvocation().getCodeGenOpts().DependentLibs;
210+
if (libs.empty()) {
211+
return;
212+
}
213+
// dependent-lib is currently only supported on Windows, so the list should be
214+
// empty on non-Windows platforms
215+
assert(
216+
llvm::Triple(ci.getInvocation().getTargetOpts().triple).isOSWindows() &&
217+
"--dependent-lib is only supported on Windows");
218+
// Add linker options specified by --dependent-lib
219+
auto builder = mlir::OpBuilder(mlirModule.getRegion());
220+
for (const std::string &lib : libs) {
221+
builder.create<mlir::LLVM::LinkerOptionsOp>(
222+
mlirModule.getLoc(), builder.getStrArrayAttr({"/DEFAULTLIB:", lib}));
223+
}
224+
}
225+
206226
bool CodeGenAction::beginSourceFileAction() {
207227
llvmCtx = std::make_unique<llvm::LLVMContext>();
208228
CompilerInstance &ci = this->getInstance();
@@ -304,6 +324,9 @@ bool CodeGenAction::beginSourceFileAction() {
304324
Fortran::parser::Program &parseTree{*ci.getParsing().parseTree()};
305325
lb.lower(parseTree, ci.getInvocation().getSemanticsContext());
306326

327+
// Add dependent libraries
328+
addDepdendentLibs(*mlirModule, ci);
329+
307330
// run the default passes.
308331
mlir::PassManager pm((*mlirModule)->getName(),
309332
mlir::OpPassManager::Nesting::Implicit);

flang/test/Driver/dependent-lib.f90

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
! REQUIRES aarch64-registered-target && x86-registered-target
2+
! DEFINE: %{triple} =
3+
! DEFINE: %{compile} = %flang_fc1 -emit-mlir -triple %{triple} --dependent-lib=libtest %s -o - 2>&1
4+
! REDEFINE: %{triple} = aarch64-pc-windows-msvc
5+
! RUN: %{compile} | FileCheck %s
6+
! REDEFINE: %{triple} = x86_64-pc-windows-msvc
7+
! RUN: %{compile} | FileCheck %s
8+
! REDEFINE: %{triple} = x86_64-linux-unknown-gnu
9+
! RUN: not %{compile} | FileCheck %s --check-prefixes=CHECK-NOWIN
10+
! REDEFINE: %{triple} = aarch64-apple-darwin
11+
! RUN: not %{compile} | FileCheck %s --check-prefixes=CHECK-NOWIN
12+
13+
! CHECK: llvm.linker_options ["/DEFAULTLIB:", "libtest"]
14+
program test
15+
end program test
16+
! CHECK-NOWIN: --dependent-lib is only supported on Windows

flang/test/Driver/driver-help.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
! HELP-FC1-EMPTY:
142142
! HELP-FC1-NEXT:OPTIONS:
143143
! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros
144+
! HELP-FC1-NEXT: --dependent-lib=<value> Add dependent library
144145
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
145146
! HELP-FC1-NEXT: -emit-fir Build the parse tree, then lower it to FIR
146147
! HELP-FC1-NEXT: -emit-hlfir Build the parse tree, then lower it to HLFIR

0 commit comments

Comments
 (0)