Skip to content

Commit

Permalink
[flang] Add runtimes using --dependent-lib on MSVC targets (#72519)
Browse files Browse the repository at this point in the history
This patch uses the added --dependent-lib support to add the relevant
runtimes on MSVC targets as `/DEFAULTLIB:` sections in the object file
rather than on the link line. This should help CMake support for flang
on Windows.

Fixes #63741 
Fixes #68017
  • Loading branch information
DavidTruby authored Nov 23, 2023
1 parent 6727526 commit 0bc7cd4
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 86 deletions.
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 @@ -564,7 +564,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 @@ -226,7 +226,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
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

0 comments on commit 0bc7cd4

Please sign in to comment.