-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang] Add dependent-lib option to flang -fc1 on Windows #72121
Conversation
This patch adds a --depdendent-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.
@llvm/pr-subscribers-flang-driver @llvm/pr-subscribers-clang Author: David Truby (DavidTruby) ChangesThis patch adds a --depdendent-lib option to flang -fc1 on Windows to Full diff: https://github.com/llvm/llvm-project/pull/72121.diff 6 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d1b67a448b2a59b..c7eb52145f614b4 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 d7ca7b66584dd52..8df966571bc39ab 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();
@@ -303,6 +323,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..e455d06258662a1
--- /dev/null
+++ b/flang/test/Driver/dependent-lib.f90
@@ -0,0 +1,7 @@
+
+! RUN: %flang_fc1 -emit-mlir -triple aarch64-pc-windows-msvc --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-mlir -triple x86_64-pc-windows-msvc --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s
+
+! CHECK: llvm.linker_options ["/DEFAULTLIB:", "libtest"]
+program test
+end program test
\ No newline at end of file
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see contributions for supporting Windows, thank you David!
flang/test/Driver/dependent-lib.f90
Outdated
|
||
! CHECK: llvm.linker_options ["/DEFAULTLIB:", "libtest"] | ||
program test | ||
end program test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing EOF?
flang/test/Driver/dependent-lib.f90
Outdated
@@ -0,0 +1,7 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] This line can be skipped?
// Add dependent libraries | ||
addDepdendentLibs(*mlirModule, ci); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the semantics of "dependent-lib" - what's the consumer of this flag? Wondering whether this isn't too early in the compilation to call this hook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The consumer is that an LLVMIR dialect operation should be added to the MLIR module (in the global module scope) that will eventually get lowered by the standard MLIR LLVM dialect to LLVM ir transform. I don’t think it particularly matters where in the compilation flow that gets added as it doesn’t affect or get affected by any other transformation. I’m happy to add it later if you have a suggestion where it should be done, I mostly did it here because you still have all the information to construct the list of linker options without needing to pass any information further on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I thought that this was FrontendAction::beginSourceFile rather than CodeGenAction::beginSourceFileAction()
.
I think that keeping it here is fine. Like you said, the ordering in this case doesn't matter that much.
flang/test/Driver/dependent-lib.f90
Outdated
! RUN: %flang_fc1 -emit-mlir -triple aarch64-pc-windows-msvc --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s | ||
! RUN: %flang_fc1 -emit-mlir -triple x86_64-pc-windows-msvc --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] If you only want to check the triple, then you could use LIT's DEFINE
/REDEFINE
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed to use this but I'm not sure it's actually any clearer than just listing the run lines. Let me know what you think now that I've put it in 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with Andrzej's comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM :)
Thank you for addressing my comments.
flang/test/Driver/dependent-lib.f90
Outdated
! DEFINE: %{triple} = | ||
! DEFINE: %{run} = %flang_fc1 -emit-mlir -triple %{triple} --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s | ||
! REDEFINE: %{triple} = aarch64-pc-windows-msvc | ||
! RUN: %{run} | ||
! REDEFINE: %{triple} = x86_64-pc-windows-msvc | ||
! RUN: %{run} | ||
! REDEFINE: %{triple} = x86_64-linux-unknown-gnu | ||
! RUN: not %{run} --check-prefixes=CHECK-NOWIN | ||
! REDEFINE: %{triple} = aarch64-apple-darwin | ||
! RUN: not %{run} --check-prefixes=CHECK-NOWIN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you meant about readability - indeed debatable 😅 . Here's an idea how to improve it a bit:
! DEFINE: %{triple} = | |
! DEFINE: %{run} = %flang_fc1 -emit-mlir -triple %{triple} --dependent-lib=libtest %s -o - 2>&1 | FileCheck %s | |
! REDEFINE: %{triple} = aarch64-pc-windows-msvc | |
! RUN: %{run} | |
! REDEFINE: %{triple} = x86_64-pc-windows-msvc | |
! RUN: %{run} | |
! REDEFINE: %{triple} = x86_64-linux-unknown-gnu | |
! RUN: not %{run} --check-prefixes=CHECK-NOWIN | |
! REDEFINE: %{triple} = aarch64-apple-darwin | |
! RUN: not %{run} --check-prefixes=CHECK-NOWIN | |
! 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 |
(separating the compiler invocation from the FileCheck invocation as two logically seperate things).
This is a "nit" - I am happy with this test as long as the functionality is verified (it is).
// Add dependent libraries | ||
addDepdendentLibs(*mlirModule, ci); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I thought that this was FrontendAction::beginSourceFile rather than CodeGenAction::beginSourceFileAction()
.
I think that keeping it here is fine. Like you said, the ordering in this case doesn't matter that much.
hello! looks like this broke some bots: |
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 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.