flang: package standalone flang with LLVM 20+ driver fixes
Wire flang into llvmPackages as a first-class Fortran compiler. flang
is built standalone on top of the LLVM/clang package set rather than
bundled into the llvm derivation, with passthru metadata
(`langFortran`, `isFlang`, `isClang`, `hardeningUnsupportedFlags`) so
cc-wrapper and downstream tooling can detect and adapt to it.
Driver compatibility patches backported from upstream are applied
selectively per LLVM version:
* `use-xflang-in-diagnostics` is applied to LLVM 20 and newer; it
teaches the driver to suggest `-Xflang` instead of `-Xclang` in
error messages for options only available to `flang -fc1`.
* `warn-on-fbuiltin-and-fno-builtin` and
`accept-and-ignore-some-gfortran-optimization-flags` are applied
to LLVM 20 and 21 only. LLVM 22 has equivalent behaviour merged
upstream (`warn_drv_invalid_argument_for_flang` and
`clang_ignored_gcc_optimization_f_Group` handling in
clang/lib/Driver/ToolChains/Flang.cpp), so the patches are skipped
there.
Patches live under pkgs/development/compilers/llvm/21/flang/ and are
shared across versions via patches.nix. They are applied to a private
libclang variant rather than the flang source tree because standalone
flang resolves driver/option definitions through the installed libclang
package.
Two focused passthru tests are added:
* `compile-smoke` exercises basic compilation and `@response-file`
handling.
* `driver-flags` covers wrapper flag isolation
(`NIX_CFLAGS_COMPILE` must not leak into flang;
`NIX_FFLAGS_COMPILE` must reach it), the backported driver
diagnostics, and regression coverage for previously hard-erroring
flags.
Build on the earlier standalone flang work by @picostove.
Co-authored-by: stove <stove@rivosinc.com>
Co-authored-by: acture <acture@gmail.com>
Co-authored-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
+49
@@ -0,0 +1,49 @@
|
||||
From da7174958be43d69b2ed6b581c8ac8a382b59180 Mon Sep 17 00:00:00 2001
|
||||
From: Tarun Prabhu <tarun.prabhu@gmail.com>
|
||||
Date: Tue, 28 Oct 2025 19:35:27 -0600
|
||||
Subject: [PATCH] [flang][Driver] Accept (and ignore) some gfortran-specific
|
||||
options
|
||||
|
||||
Enable the clang_ignored_gcc_optimization_f_group in flang. These options are
|
||||
accepted by clang, but ignored after emitting a warning message. flang's
|
||||
behavior now mirrors clang.
|
||||
|
||||
Fixes #158436
|
||||
---
|
||||
clang/include/clang/Driver/Options.td | 3 ++-
|
||||
clang/lib/Driver/ToolChains/Flang.cpp | 8 ++++++++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
|
||||
index ef1c8758705f4..cac122d296624 100644
|
||||
--- a/include/clang/Driver/Options.td
|
||||
+++ b/include/clang/Driver/Options.td
|
||||
@@ -316,7 +316,8 @@ def mno_mpx : Flag<["-"], "mno-mpx">, Group<clang_ignored_legacy_options_Group>;
|
||||
|
||||
// Group that ignores all gcc optimizations that won't be implemented
|
||||
def clang_ignored_gcc_optimization_f_Group : OptionGroup<
|
||||
- "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>;
|
||||
+ "<clang_ignored_gcc_optimization_f_Group>">,
|
||||
+ Group<f_Group>, Flags<[Ignored]>, Visibility<[ClangOption, FlangOption]>;
|
||||
|
||||
class DiagnosticOpts<string base>
|
||||
: KeyPathAndMacro<"DiagnosticOpts->", base, "DIAG_"> {}
|
||||
diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp
|
||||
index 88bce181d40d2..2f5e93d139858 100644
|
||||
--- a/lib/Driver/ToolChains/Flang.cpp
|
||||
+++ b/lib/Driver/ToolChains/Flang.cpp
|
||||
@@ -858,6 +858,14 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
if (const Arg *A = Args.getLastArg(Opt))
|
||||
D.Diag(diag::warn_drv_invalid_argument_for_flang) << A->getSpelling();
|
||||
|
||||
+ // Warn about options that are ignored by flang. These are options that are
|
||||
+ // accepted by gfortran, but have no equivalent in flang.
|
||||
+ for (const Arg *A :
|
||||
+ Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
|
||||
+ D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
|
||||
+ A->claim();
|
||||
+ }
|
||||
+
|
||||
const InputInfo &Input = Inputs[0];
|
||||
types::ID InputType = Input.getType();
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
From 9ab9d33171ee35c948967a2a2d714b8059887607 Mon Sep 17 00:00:00 2001
|
||||
From: Tarun Prabhu <tarun@lanl.gov>
|
||||
Date: Wed, 29 Oct 2025 09:13:17 -0600
|
||||
Subject: [PATCH] [flang][driver] Use -Xflang in diagnostics
|
||||
|
||||
When an option that is only available in `flang -fc1` is provided to
|
||||
`flang`, emit a diagnostic with a suggestion containing "did you mean
|
||||
-Xflang '-foo'".
|
||||
|
||||
Partially addresses #163550.
|
||||
---
|
||||
clang/lib/Driver/Driver.cpp | 15 ++++++++++++---
|
||||
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
|
||||
index 40ea513e85427..71c52807091ba 100644
|
||||
--- a/lib/Driver/Driver.cpp
|
||||
+++ b/lib/Driver/Driver.cpp
|
||||
@@ -365,9 +365,18 @@
|
||||
auto ArgString = A->getAsString(Args);
|
||||
std::string Nearest;
|
||||
if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
|
||||
- if (!IsCLMode() &&
|
||||
- getOpts().findExact(ArgString, Nearest,
|
||||
- llvm::opt::Visibility(options::CC1Option))) {
|
||||
+ if (IsFlangMode()) {
|
||||
+ if (getOpts().findExact(ArgString, Nearest,
|
||||
+ llvm::opt::Visibility(options::FC1Option))) {
|
||||
+ DiagID = diag::err_drv_unknown_argument_with_suggestion;
|
||||
+ Diags.Report(DiagID) << ArgString << "-Xflang " + Nearest;
|
||||
+ } else {
|
||||
+ DiagID = diag::err_drv_unknown_argument;
|
||||
+ Diags.Report(DiagID) << ArgString;
|
||||
+ }
|
||||
+ } else if (!IsCLMode() && getOpts().findExact(ArgString, Nearest,
|
||||
+ llvm::opt::Visibility(
|
||||
+ options::CC1Option))) {
|
||||
DiagID = diag::err_drv_unknown_argument_with_suggestion;
|
||||
Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest;
|
||||
} else {
|
||||
@@ -0,0 +1,74 @@
|
||||
From 263377a175709c2d11f3ff63c2d2d2843afb91ea Mon Sep 17 00:00:00 2001
|
||||
From: Tarun Prabhu <tarun@lanl.gov>
|
||||
Date: Thu, 23 Oct 2025 13:24:20 -0600
|
||||
Subject: [PATCH] [flang][Driver] Warn on -fbuiltin and -fno-builtin
|
||||
|
||||
The options -fbuiltin and -fno-builtin are not valid for Fortran. However,
|
||||
they are accepted by gfortran which emits a warning message but continues to
|
||||
compile the code. Both -fbuiltin and -fno-builtin have been enabled for flang.
|
||||
Specifying either will result in a warning message being shown but no other
|
||||
effects. Compilation will proceed normally after these warnings are shown. This
|
||||
brings flang's behavior in line with gfortran for these options.
|
||||
|
||||
Fixes #164766
|
||||
---
|
||||
clang/include/clang/Basic/DiagnosticDriverKinds.td | 3 +++
|
||||
clang/include/clang/Driver/Options.td | 4 ++--
|
||||
clang/lib/Driver/ToolChains/Flang.cpp | 7 +++++++
|
||||
3 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
|
||||
index 0581bf353d936..83980e3ac35b7 100644
|
||||
--- a/include/clang/Basic/DiagnosticDriverKinds.td
|
||||
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
|
||||
@@ -131,6 +131,9 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
|
||||
def warn_drv_unsupported_option_for_target : Warning<
|
||||
"ignoring '%0' option as it is not currently supported for target '%1'">,
|
||||
InGroup<OptionIgnored>;
|
||||
+def warn_drv_invalid_argument_for_flang : Warning<
|
||||
+ "'%0' is not valid for Fortran">,
|
||||
+ InGroup<OptionIgnored>;
|
||||
def warn_drv_unsupported_option_for_flang : Warning<
|
||||
"the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">,
|
||||
InGroup<OptionIgnored>;
|
||||
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
|
||||
index ef1c8758705f4..bca8b26bc3d30 100644
|
||||
--- a/include/clang/Driver/Options.td
|
||||
+++ b/include/clang/Driver/Options.td
|
||||
@@ -1940,7 +1940,7 @@ defm borland_extensions : BoolFOption<"borland-extensions",
|
||||
"Accept non-standard constructs supported by the Borland compiler">,
|
||||
NegFlag<SetFalse>>;
|
||||
def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>,
|
||||
- Visibility<[ClangOption, CLOption, DXCOption]>;
|
||||
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption, FC1Option]>;
|
||||
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
|
||||
Flags<[]>, HelpText<"Load the clang builtins module map file.">;
|
||||
defm caret_diagnostics : BoolFOption<"caret-diagnostics",
|
||||
@@ -3493,7 +3493,7 @@ def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">,
|
||||
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoNegativeFlag<CodeGenOpts<"AssumeSaneOperatorNew">>;
|
||||
def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>,
|
||||
- Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
|
||||
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FlangOption, FC1Option]>,
|
||||
HelpText<"Disable implicit builtin knowledge of functions">;
|
||||
def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
|
||||
diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp
|
||||
index a56fa41c49d34..88bce181d40d2 100644
|
||||
--- a/lib/Driver/ToolChains/Flang.cpp
|
||||
+++ b/lib/Driver/ToolChains/Flang.cpp
|
||||
@@ -851,6 +851,13 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
assert(false && "Unexpected action class for Flang tool.");
|
||||
}
|
||||
|
||||
+ // We support some options that are invalid for Fortran and have no effect.
|
||||
+ // These are solely for compatibility with other compilers. Emit a warning if
|
||||
+ // any such options are provided, then proceed normally.
|
||||
+ for (options::ID Opt : {options::OPT_fbuiltin, options::OPT_fno_builtin})
|
||||
+ if (const Arg *A = Args.getLastArg(Opt))
|
||||
+ D.Diag(diag::warn_drv_invalid_argument_for_flang) << A->getSpelling();
|
||||
+
|
||||
const InputInfo &Input = Inputs[0];
|
||||
types::ID InputType = Input.getType();
|
||||
|
||||
@@ -476,28 +476,93 @@ makeScopeWithSplicing' {
|
||||
// lib.optionalAttrs (lib.versionAtLeast metadata.release_version "19") {
|
||||
bolt = callPackage ./bolt { };
|
||||
}
|
||||
// lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") {
|
||||
flang = callPackage ./flang { };
|
||||
// lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") (
|
||||
let
|
||||
# Standalone flang still resolves driver/option definitions via the
|
||||
# installed libclang package, so keep flang-specific driver backports
|
||||
# in a private libclang variant instead of patching the flang source
|
||||
# tree. The `-Xflang` diagnostic improvement applies to every
|
||||
# supported standalone-flang version (20+); the other two backports
|
||||
# are only needed up to LLVM 21 because upstream merged equivalent
|
||||
# behaviour into LLVM 22.
|
||||
flangDriverPatches =
|
||||
lib.optionals (lib.versionAtLeast metadata.release_version "20") [
|
||||
(metadata.getVersionFile "flang/use-xflang-in-diagnostics.patch")
|
||||
]
|
||||
++
|
||||
lib.optionals
|
||||
(lib.versionAtLeast metadata.release_version "20" && lib.versionOlder metadata.release_version "22")
|
||||
[
|
||||
(metadata.getVersionFile "flang/warn-on-fbuiltin-and-fno-builtin.patch")
|
||||
(metadata.getVersionFile "flang/accept-and-ignore-some-gfortran-optimization-flags.patch")
|
||||
];
|
||||
flangLibclang =
|
||||
if flangDriverPatches == [ ] then
|
||||
self.libclang
|
||||
else
|
||||
self.libclang.override {
|
||||
extraPatches = flangDriverPatches;
|
||||
};
|
||||
flangUnwrapped = callPackage ./flang {
|
||||
libclang = flangLibclang;
|
||||
};
|
||||
flangRt = callPackage ./flang-rt {
|
||||
buildFlang = buildLlvmPackages.flang-unwrapped;
|
||||
};
|
||||
in
|
||||
{
|
||||
flang-unwrapped = flangUnwrapped;
|
||||
flang-rt = flangRt;
|
||||
flang =
|
||||
let
|
||||
wrapped = wrapCCWith rec {
|
||||
cc = flangUnwrapped;
|
||||
bintools = bintools';
|
||||
extraPackages = [ targetLlvmPackages.flang-rt ];
|
||||
extraBuildCommands = mkExtraBuildCommands0 cc + ''
|
||||
# triplet however is not used in darwin
|
||||
PLATFORM_DIR="${if stdenv.targetPlatform.isDarwin then "darwin" else stdenv.targetPlatform.config}"
|
||||
RT_LIB_PATH="${targetLlvmPackages.flang-rt}/lib/clang/${clangVersion}/lib/$PLATFORM_DIR"
|
||||
if [ -d "$RT_LIB_PATH" ]; then
|
||||
ln -s "$RT_LIB_PATH" "$rsrc"/lib
|
||||
echo "-L$rsrc/lib" >> $out/nix-support/cc-ldflags
|
||||
else
|
||||
ln -s "${targetLlvmPackages.flang-rt}/lib" "$rsrc"/lib
|
||||
echo "-L$rsrc/lib" >> $out/nix-support/cc-ldflags
|
||||
fi
|
||||
'';
|
||||
};
|
||||
tests = callPackage ./flang/tests.nix {
|
||||
flang = wrapped;
|
||||
};
|
||||
in
|
||||
wrapped
|
||||
// {
|
||||
passthru = (wrapped.passthru or { }) // {
|
||||
inherit tests;
|
||||
};
|
||||
};
|
||||
|
||||
libc-overlay = callPackage ./libc {
|
||||
isFullBuild = false;
|
||||
# Use clang due to "gnu::naked" not working on aarch64.
|
||||
# Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
|
||||
stdenv = overrideCC stdenv buildLlvmPackages.clang;
|
||||
};
|
||||
libc-overlay = callPackage ./libc {
|
||||
isFullBuild = false;
|
||||
# Use clang due to "gnu::naked" not working on aarch64.
|
||||
# Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
|
||||
stdenv = overrideCC stdenv buildLlvmPackages.clang;
|
||||
};
|
||||
|
||||
libc-full = callPackage ./libc {
|
||||
isFullBuild = true;
|
||||
# Use clang due to "gnu::naked" not working on aarch64.
|
||||
# Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
|
||||
stdenv = overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt;
|
||||
# FIXME: This should almost certainly be `stdenv.hostPlatform`.
|
||||
cmake = if stdenv.targetPlatform.libc == "llvm" then cmakeMinimal else cmake;
|
||||
python3 = if stdenv.targetPlatform.libc == "llvm" then python3Minimal else python3;
|
||||
};
|
||||
libc-full = callPackage ./libc {
|
||||
isFullBuild = true;
|
||||
# Use clang due to "gnu::naked" not working on aarch64.
|
||||
# Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
|
||||
stdenv = overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt;
|
||||
# FIXME: This should almost certainly be `stdenv.hostPlatform`.
|
||||
cmake = if stdenv.targetPlatform.libc == "llvm" then cmakeMinimal else cmake;
|
||||
python3 = if stdenv.targetPlatform.libc == "llvm" then python3Minimal else python3;
|
||||
};
|
||||
|
||||
libc =
|
||||
# FIXME: This should almost certainly be `stdenv.hostPlatform`.
|
||||
if stdenv.targetPlatform.libc == "llvm" then self.libc-full else self.libc-overlay;
|
||||
};
|
||||
libc =
|
||||
# FIXME: This should almost certainly be `stdenv.hostPlatform`.
|
||||
if stdenv.targetPlatform.libc == "llvm" then self.libc-full else self.libc-overlay;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,21 +23,27 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "flang";
|
||||
inherit version;
|
||||
|
||||
src = runCommand "flang-src-${version}" { inherit (monorepoSrc) passthru; } ''
|
||||
mkdir -p "$out"
|
||||
cp -r ${monorepoSrc}/${finalAttrs.pname} "$out"
|
||||
cp -r ${monorepoSrc}/cmake "$out"
|
||||
cp -r ${monorepoSrc}/llvm "$out"
|
||||
cp -r ${monorepoSrc}/clang "$out"
|
||||
cp -r ${monorepoSrc}/mlir "$out"
|
||||
cp -r ${monorepoSrc}/third-party "$out"
|
||||
chmod -R +w $out/llvm
|
||||
'';
|
||||
src =
|
||||
runCommand "${finalAttrs.pname}-src-${finalAttrs.version}"
|
||||
{
|
||||
inherit (monorepoSrc) passthru;
|
||||
}
|
||||
''
|
||||
mkdir -p "$out"
|
||||
cp -r ${monorepoSrc}/${finalAttrs.pname} "$out"
|
||||
cp -r ${monorepoSrc}/cmake "$out"
|
||||
cp -r ${monorepoSrc}/llvm "$out"
|
||||
cp -r ${monorepoSrc}/clang "$out"
|
||||
cp -r ${monorepoSrc}/mlir "$out"
|
||||
cp -r ${monorepoSrc}/third-party "$out"
|
||||
cp -r ${monorepoSrc}/flang-rt "$out"
|
||||
chmod -R +w $out/llvm
|
||||
'';
|
||||
|
||||
patches = [
|
||||
./dummy_target_19+.patch
|
||||
];
|
||||
patchFlags = [ "-p2" ];
|
||||
patchFlags = [ "-p1" ];
|
||||
|
||||
sourceRoot = "${finalAttrs.src.name}/flang";
|
||||
|
||||
@@ -62,24 +68,36 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
ls -l ${mlir.dev}/lib/cmake/mlir/MLIRConfig.cmake
|
||||
'';
|
||||
cmakeFlags = [
|
||||
(lib.cmakeBool "CMAKE_VERBOSE_MAKEFILE" true)
|
||||
(lib.cmakeFeature "LLVM_DIR" "${libllvm.dev}/lib/cmake/llvm")
|
||||
# TODO: Needs patches and the `lit` package like other LLVM builds?
|
||||
(lib.cmakeFeature "LLVM_TOOLS_BINARY_DIR" "${buildLlvmPackages.tblgen}/bin/")
|
||||
(lib.cmakeFeature "LLVM_EXTERNAL_LIT" "${buildLlvmPackages.tblgen}/bin/llvm-lit")
|
||||
(lib.cmakeFeature "CLANG_DIR" "${libclang.dev}/lib/cmake/clang")
|
||||
(lib.cmakeFeature "MLIR_DIR" "${mlir.dev}/lib/cmake/mlir")
|
||||
(lib.cmakeFeature "MLIR_TABLEGEN_EXE" "${buildLlvmPackages.tblgen}/bin/mlir-tblgen")
|
||||
(lib.cmakeFeature "MLIR_TABLEGEN_TARGET" "MLIR-TBLGen")
|
||||
(lib.cmakeBool "LLVM_BUILD_EXAMPLES" false)
|
||||
(lib.cmakeBool "MLIR_LINK_MLIR_DYLIB" (!stdenv.hostPlatform.isStatic))
|
||||
(lib.cmakeFeature "LLVM_LIT_ARGS" "-v")
|
||||
(lib.cmakeBool "LLVM_ENABLE_PLUGINS" false)
|
||||
(lib.cmakeBool "FLANG_STANDALONE_BUILD" true)
|
||||
(lib.cmakeBool "LLVM_INCLUDE_EXAMPLES" false)
|
||||
(lib.cmakeBool "FLANG_INCLUDE_TESTS" false)
|
||||
|
||||
]
|
||||
++ devExtraCmakeFlags;
|
||||
|
||||
passthru = {
|
||||
# Used by cc-wrapper to determine whether or not the default setup hook is enabled.
|
||||
langC = false;
|
||||
langCC = false;
|
||||
langFortran = true;
|
||||
isClang = true;
|
||||
isFlang = true;
|
||||
|
||||
hardeningUnsupportedFlags = [
|
||||
"zerocallusedregs"
|
||||
"stackprotector"
|
||||
"stackclashprotection"
|
||||
];
|
||||
};
|
||||
|
||||
postUnpack = ''
|
||||
chmod -R u+w -- $sourceRoot/..
|
||||
'';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 070c39eb6e9a..168c97524943 100644
|
||||
--- a/flang/CMakeLists.txt
|
||||
+++ b/flang/CMakeLists.txt
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -1,6 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
set(LLVM_SUBPROJECT_TITLE "Flang")
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
runCommand,
|
||||
flang,
|
||||
}:
|
||||
let
|
||||
flangExe = "${flang}/bin/flang";
|
||||
writeHello = ''
|
||||
cat > hello.f90 <<'EOF'
|
||||
program hello
|
||||
end program hello
|
||||
EOF
|
||||
'';
|
||||
in
|
||||
{
|
||||
compile-smoke = runCommand "flang-compile-smoke" { } ''
|
||||
set -euo pipefail
|
||||
|
||||
${writeHello}
|
||||
|
||||
${flangExe} -c hello.f90 -o compile.o
|
||||
[ -f compile.o ]
|
||||
|
||||
cat > args.rsp <<'EOF'
|
||||
-c
|
||||
hello.f90
|
||||
-o
|
||||
response.o
|
||||
EOF
|
||||
|
||||
${flangExe} @args.rsp
|
||||
[ -f response.o ]
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
||||
driver-flags = runCommand "flang-driver-flags" { } ''
|
||||
set -euo pipefail
|
||||
|
||||
${writeHello}
|
||||
|
||||
${flangExe} -### -c hello.f90 > no-seed.log 2>&1
|
||||
if grep -F -- "-frandom-seed=" no-seed.log; then
|
||||
echo "wrapper unexpectedly injected -frandom-seed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Confirm that user-supplied NIX_CFLAGS_COMPILE does not leak into the
|
||||
# Fortran wrapper invocation: the wrapper must source flags from
|
||||
# NIX_FFLAGS_COMPILE only, so a marker placed in NIX_CFLAGS_COMPILE
|
||||
# must not appear in the resulting flang command line.
|
||||
NIX_CFLAGS_COMPILE="-Icflags-leak-marker-include" \
|
||||
${flangExe} -### -c hello.f90 > cflags-isolation.log 2>&1
|
||||
if grep -F -- "cflags-leak-marker-include" cflags-isolation.log; then
|
||||
echo "NIX_CFLAGS_COMPILE leaked into the flang wrapper" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Confirm that NIX_FFLAGS_COMPILE is the user-facing channel for
|
||||
# Fortran flags and flows through to the driver.
|
||||
NIX_FFLAGS_COMPILE="-Iffflags-marker-include" \
|
||||
${flangExe} -### -c hello.f90 > fflags-passthrough.log 2>&1
|
||||
grep -F -- "ffflags-marker-include" fflags-passthrough.log
|
||||
|
||||
${flangExe} -### -fbuiltin -fno-builtin hello.f90 > builtin.log 2>&1
|
||||
grep -F -- "warning: '-fbuiltin' is not valid for Fortran" builtin.log
|
||||
grep -F -- "warning: '-fno-builtin' is not valid for Fortran" builtin.log
|
||||
if grep -F -- "error: unknown argument" builtin.log; then
|
||||
echo "builtin compatibility flags unexpectedly failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${flangExe} -### -fexpensive-optimizations hello.f90 > ignored-flag.log 2>&1
|
||||
grep -F -- "optimization flag '-fexpensive-optimizations' is not supported" ignored-flag.log
|
||||
if grep -F -- "error: unknown argument" ignored-flag.log; then
|
||||
echo "ignored gfortran-style flag unexpectedly failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ${flangExe} -### -complex-range=full hello.f90 > suggestion.log 2>&1; then
|
||||
echo "expected -complex-range=full to fail at the driver layer" >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -F -- "error: unknown argument '-complex-range=full'" suggestion.log
|
||||
grep -F -- "did you mean '-Xflang -complex-range=full'" suggestion.log
|
||||
if grep -F -- "-Xclang -complex-range=full" suggestion.log; then
|
||||
echo "driver suggested -Xclang instead of -Xflang" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch $out
|
||||
'';
|
||||
}
|
||||
@@ -138,4 +138,24 @@
|
||||
path = ../19;
|
||||
}
|
||||
];
|
||||
"flang/warn-on-fbuiltin-and-fno-builtin.patch" = [
|
||||
{
|
||||
after = "20";
|
||||
before = "22";
|
||||
path = ../21;
|
||||
}
|
||||
];
|
||||
"flang/accept-and-ignore-some-gfortran-optimization-flags.patch" = [
|
||||
{
|
||||
after = "20";
|
||||
before = "22";
|
||||
path = ../21;
|
||||
}
|
||||
];
|
||||
"flang/use-xflang-in-diagnostics.patch" = [
|
||||
{
|
||||
after = "20";
|
||||
path = ../21;
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user