Skip to content

[flang] Add runtimes using --dependent-lib on MSVC targets #72519

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

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 4 additions & 40 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,47 +977,11 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
return true;
}

void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
void tools::addFortranRuntimeLibs(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs) {
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back(Args.MakeArgString(
"/DEFAULTLIB:" + TC.getCompilerRTBasename(Args, "builtins")));
unsigned RTOptionID = options::OPT__SLASH_MT;
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
.Case("static", options::OPT__SLASH_MT)
.Case("static_dbg", options::OPT__SLASH_MTd)
.Case("dll", options::OPT__SLASH_MD)
.Case("dll_dbg", options::OPT__SLASH_MDd)
.Default(options::OPT__SLASH_MT);
}
switch (RTOptionID) {
case options::OPT__SLASH_MT:
CmdArgs.push_back("/DEFAULTLIB:libcmt");
CmdArgs.push_back("Fortran_main.static.lib");
CmdArgs.push_back("FortranRuntime.static.lib");
CmdArgs.push_back("FortranDecimal.static.lib");
break;
case options::OPT__SLASH_MTd:
CmdArgs.push_back("/DEFAULTLIB:libcmtd");
CmdArgs.push_back("Fortran_main.static_dbg.lib");
CmdArgs.push_back("FortranRuntime.static_dbg.lib");
CmdArgs.push_back("FortranDecimal.static_dbg.lib");
break;
case options::OPT__SLASH_MD:
CmdArgs.push_back("/DEFAULTLIB:msvcrt");
CmdArgs.push_back("Fortran_main.dynamic.lib");
CmdArgs.push_back("FortranRuntime.dynamic.lib");
CmdArgs.push_back("FortranDecimal.dynamic.lib");
break;
case options::OPT__SLASH_MDd:
CmdArgs.push_back("/DEFAULTLIB:msvcrtd");
CmdArgs.push_back("Fortran_main.dynamic_dbg.lib");
CmdArgs.push_back("FortranRuntime.dynamic_dbg.lib");
CmdArgs.push_back("FortranDecimal.dynamic_dbg.lib");
break;
}
} else {
// These are handled earlier on Windows by telling the frontend driver to add
// the correct libraries to link against as dependents in the object file.
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back("-lFortran_main");
CmdArgs.push_back("-lFortranRuntime");
CmdArgs.push_back("-lFortranDecimal");
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
bool IsOffloadingHost = false, bool GompNeedsRT = false);

/// Adds Fortran runtime libraries to \p CmdArgs.
void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args,
void addFortranRuntimeLibs(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs);

/// Adds the path for the Fortran runtime libraries to \p CmdArgs.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// to generate executables.
if (getToolChain().getDriver().IsFlangMode()) {
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), CmdArgs);
}

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/DragonFly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
CmdArgs.push_back("-lm");
}

Expand Down
57 changes: 57 additions & 0 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,59 @@ void Flang::AddAArch64TargetArgs(const ArgList &Args,
}
}

static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
assert(TC.getTriple().isKnownWindowsMSVCEnvironment() &&
"can only add VS runtime library on Windows!");
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins")));
}
unsigned RTOptionID = options::OPT__SLASH_MT;
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
.Case("static", options::OPT__SLASH_MT)
.Case("static_dbg", options::OPT__SLASH_MTd)
.Case("dll", options::OPT__SLASH_MD)
.Case("dll_dbg", options::OPT__SLASH_MDd)
.Default(options::OPT__SLASH_MT);
}
switch (RTOptionID) {
case options::OPT__SLASH_MT:
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("--dependent-lib=libcmt");
CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib");
break;
case options::OPT__SLASH_MTd:
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("--dependent-lib=libcmtd");
CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib");
break;
case options::OPT__SLASH_MD:
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DLL");
CmdArgs.push_back("--dependent-lib=msvcrt");
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib");
break;
case options::OPT__SLASH_MDd:
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_DLL");
CmdArgs.push_back("--dependent-lib=msvcrtd");
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib");
break;
}
}

void Flang::addTargetOptions(const ArgList &Args,
ArgStringList &CmdArgs) const {
const ToolChain &TC = getToolChain();
Expand Down Expand Up @@ -267,6 +320,10 @@ void Flang::addTargetOptions(const ArgList &Args,
}
}

if (Triple.isKnownWindowsMSVCEnvironment()) {
processVSRuntimeLibrary(TC, Args, CmdArgs);
}

// TODO: Add target specific flags, ABI, mtune option etc.
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/FreeBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
if (Profiling)
CmdArgs.push_back("-lm_p");
else
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
CmdArgs.push_back("-lm");
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Haiku.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
}

CmdArgs.push_back("-lgcc");
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/MSVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,

if (C.getDriver().IsFlangMode()) {
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, CmdArgs);

// Inform the MSVC linker that we're generating a console application, i.e.
// one with `main` as the "user-defined" entry point. The `main` function is
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/MinGW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,

if (C.getDriver().IsFlangMode()) {
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, CmdArgs);
}

// TODO: Add profile stuff here
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/NetBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
CmdArgs.push_back("-lm");
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/OpenBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, CmdArgs);
if (Profiling)
CmdArgs.push_back("-lm_p");
else
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Solaris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// these dependencies need to be listed before the C runtime below.
if (D.IsFlangMode()) {
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), CmdArgs);
CmdArgs.push_back("-lm");
}
if (Args.hasArg(options::OPT_fstack_protector) ||
Expand Down
35 changes: 0 additions & 35 deletions flang/test/Driver/linker-flags.f90
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
! but it is not needed when compiling Fortran code and they might bring in
! additional dependencies. Make sure its not added.
! RUN: %flang -### --target=aarch64-windows-msvc -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not oldnames
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=static_dbg -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DEBUG --implicit-check-not oldnames
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DLL --implicit-check-not oldnames
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC-DLL-DEBUG --implicit-check-not oldnames

! Compiler invocation to generate the object file
! CHECK-LABEL: {{.*}} "-emit-obj"
Expand Down Expand Up @@ -54,37 +51,5 @@
! (lld-)link.exe on Windows platforms. The suffix may not be added
! when the executable is not found or on non-Windows platforms.
! MSVC-LABEL: link
! MSVC-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
! MSVC-SAME: /DEFAULTLIB:libcmt
! MSVC-SAME: Fortran_main.static.lib
! MSVC-SAME: FortranRuntime.static.lib
! MSVC-SAME: FortranDecimal.static.lib
! MSVC-SAME: /subsystem:console
! MSVC-SAME: "[[object_file]]"

! MSVC-DEBUG-LABEL: link
! MSVC-DEBUG-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
! MSVC-DEBUG-SAME: /DEFAULTLIB:libcmtd
! MSVC-DEBUG-SAME: Fortran_main.static_dbg.lib
! MSVC-DEBUG-SAME: FortranRuntime.static_dbg.lib
! MSVC-DEBUG-SAME: FortranDecimal.static_dbg.lib
! MSVC-DEBUG-SAME: /subsystem:console
! MSVC-DEBUG-SAME: "[[object_file]]"

! MSVC-DLL-LABEL: link
! MSVC-DLL-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
! MSVC-DLL-SAME: /DEFAULTLIB:msvcrt
! MSVC-DLL-SAME: Fortran_main.dynamic.lib
! MSVC-DLL-SAME: FortranRuntime.dynamic.lib
! MSVC-DLL-SAME: FortranDecimal.dynamic.lib
! MSVC-DLL-SAME: /subsystem:console
! MSVC-DLL-SAME: "[[object_file]]"

! MSVC-DLL-DEBUG-LABEL: link
! MSVC-DLL-DEBUG-SAME: /DEFAULTLIB:clang_rt.builtins-aarch64.lib
! MSVC-DLL-DEBUG-SAME: /DEFAULTLIB:msvcrtd
! MSVC-DLL-DEBUG-SAME: Fortran_main.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: FortranRuntime.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: FortranDecimal.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: /subsystem:console
! MSVC-DLL-DEBUG-SAME: "[[object_file]]"
40 changes: 40 additions & 0 deletions flang/test/Driver/msvc-dependent-lib-flags.f90
Copy link
Contributor

@banach-space banach-space Nov 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some comments to clarify the difference between:

  • "msvc-dependent-lib-flags.f90", and
  • "linker-flags.f90"

Related to this, I think that renaming:

  • "linker-flags.f90" as "default-fortran-linker-flags.f90",

would really help.

Copy link
Member Author

@DavidTruby DavidTruby Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new file (msvc-dependent-lib-flags.f90) just tests this specific feature; I can probably just put that in the other linker flags file but that's getting rather big anyway and doesn't necessarily need yet more run lines added to it!
Additionally these aren't really linker flags, they're not passed to the link line explicitly by the driver but as directives in the object files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From your explanation it is clear that these files test completely different (though related) things. I would keep them separate (i agree that "linker-flags.f90" is getting long and complex).

So, is this checking the frontend driver invocation?

! MSVC: --dependent-lib=clang_rt.builtins-aarch64.lib

? That might help make the distinction clear (the other file checks the linker invocation).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these are checking the invocation of the frontend driver

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Could you add MSVC: flang-new -fc1 in there then? I feel that that part is quite important.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had to add it as just -fc1 because of the way lit does argument passing on Windows (it puts the "flang-new" and "-fc1" in quotes, but only sometimes :))

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
! RUN: %flang -### --target=aarch64-windows-msvc %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=static_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DEBUG
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL-DEBUG

! MSVC: -fc1
! MSVC-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-SAME: -D_MT
! MSVC-SAME: --dependent-lib=libcmt
! MSVC-SAME: --dependent-lib=Fortran_main.static.lib
! MSVC-SAME: --dependent-lib=FortranRuntime.static.lib
! MSVC-SAME: --dependent-lib=FortranDecimal.static.lib

! MSVC-DEBUG: -fc1
! MSVC-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DEBUG-SAME: -D_MT
! MSVC-DEBUG-SAME: -D_DEBUG
! MSVC-DEBUG-SAME: --dependent-lib=libcmtd
! MSVC-DEBUG-SAME: --dependent-lib=Fortran_main.static_dbg.lib
! MSVC-DEBUG-SAME: --dependent-lib=FortranRuntime.static_dbg.lib
! MSVC-DEBUG-SAME: --dependent-lib=FortranDecimal.static_dbg.lib

! MSVC-DLL: -fc1
! MSVC-DLL-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DLL-SAME: -D_MT
! MSVC-DLL-SAME: -D_DLL
! MSVC-DLL-SAME: --dependent-lib=msvcrt
! MSVC-DLL-SAME: --dependent-lib=Fortran_main.dynamic.lib
! MSVC-DLL-SAME: --dependent-lib=FortranRuntime.dynamic.lib
! MSVC-DLL-SAME: --dependent-lib=FortranDecimal.dynamic.lib

! MSVC-DLL-DEBUG: -fc1
! MSVC-DLL-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DLL-DEBUG-SAME: -D_MT
! MSVC-DLL-DEBUG-SAME: -D_DEBUG
! MSVC-DLL-DEBUG-SAME: -D_DLL
! MSVC-DLL-DEBUG-SAME: --dependent-lib=msvcrtd
! MSVC-DLL-DEBUG-SAME: --dependent-lib=Fortran_main.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranRuntime.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranDecimal.dynamic_dbg.lib