Package: dh-fortran
Followup-For: Bug #1146496
Control: block 1146496 by 1149705
Hi,
This is a follow-up to bug #1146496 and links with bug #1149705.
The fix for resolving 'gfortran' via its symlink in get_fc_flavor_arch() works,
but get_fc_default() checks os.environ["FC_DEFAULT"] first and calls canon(),
which still maps "gfortran" to hardcoded default_compilers["gfortran"] =
"gfortran-16". Packages setting FC_DEFAULT=gfortran (like fortran-assert) still
hit this issue.
Attached is an updated patch against dh-fortran 0.85 that:
1. Resolves symlinks in canon() and default_compilers["gfortran"] via
_detect_default_compiler("gfortran", "gfortran-16").
2. Keeps the generic upstream fallback "gfortran-16" if unversioned gfortran is
absent.
3. Adds a test in dhfortran/tests/compilers.py for FC_DEFAULT=gfortran.
Please consider applying this together with the fix for #1146496.
Thanks,
Viktor Pashaiev <[email protected]>
diff -Nru dh-fortran-0.85ubuntu1/debian/changelog dh-fortran-0.85ubuntu2/debian/changelog
--- dh-fortran-0.85ubuntu1/debian/changelog 2026-09-02 15:38:03.000000000 +0000
+++ dh-fortran-0.85ubuntu2/debian/changelog 2026-10-02 13:43:55.000000000 +0000
@@ -1,3 +1,10 @@
+dh-fortran (0.85ubuntu2) stonking; urgency=medium
+
+ * Resolve FC_DEFAULT="gfortran" to the active default gfortran on PATH
+ instead of hardcoded gfortran-16 (LP: #2169224).
+
+ -- Viktor Pashaiev <[email protected]> Fri, 02 Oct 2026 15:45:00 +0200
+
dh-fortran (0.85ubuntu1) stonking; urgency=medium
* Resolve "gfortran" via its symlink instead of the hardcoded
diff -Nru dh-fortran-0.85ubuntu1/dhfortran/compilers.py dh-fortran-0.85ubuntu2/dhfortran/compilers.py
--- dh-fortran-0.85ubuntu1/dhfortran/compilers.py 2026-09-02 15:38:03.000000000 +0000
+++ dh-fortran-0.85ubuntu2/dhfortran/compilers.py 2026-10-02 13:45:00.000000000 +0000
@@ -20,9 +20,23 @@
check_output(["dpkg-architecture", "-qDEB_HOST_MULTIARCH"]).strip().decode("utf-8")
)
+def _detect_default_compiler(cmd: str, fallback: str) -> str:
+ p = which(cmd)
+ if p is not None:
+ name = Path(p).resolve().name
+ for m in (
+ multiarch,
+ check_output(["dpkg-architecture", "-qDEB_BUILD_GNU_TYPE"]).strip().decode("utf-8"),
+ ):
+ if name.startswith(m + "-"):
+ name = name[len(m) + 1 :]
+ return name
+ return fallback
+
+
# To be updated as gfortran, flang etc are updated for new versions
default_compilers = {
- "gfortran": "gfortran-16",
+ "gfortran": _detect_default_compiler("gfortran", "gfortran-16"),
"flang": "flang-22",
"flangext": "flang-to-external-fc-18",
}
@@ -441,7 +455,7 @@
f = f77 if f77 else "/etc/alternatives/f77"
fullpath = which(f)
if fullpath is None:
- fullpath = which(default_compilers['gfortran'])
+ fullpath = which("gfortran") or which(default_compilers['gfortran'])
if fullpath is None:
if f is None:
f='gfortran' # for better error message
@@ -454,7 +468,22 @@
"""Return the default Fortran compiler"""
def canon(f):
- return default_compilers[f] if f in default_compilers else f
+ if f in default_compilers:
+ p = which(f)
+ if p is not None:
+ p_name = Path(p).resolve().name
+ for m in (
+ multiarch,
+ check_output(["dpkg-architecture", "-qDEB_BUILD_GNU_TYPE"]).strip().decode("utf-8"),
+ ):
+ if p_name.startswith(m + "-"):
+ p_name = p_name[len(m) + 1 :]
+ for c in compilers:
+ if p_name in compilers[c]["exe"]:
+ return c
+ return p_name
+ return default_compilers[f]
+ return f
if "FC_DEFAULT" in os.environ:
return canon(os.environ["FC_DEFAULT"])
if fc is not None:
diff -Nru dh-fortran-0.85ubuntu1/dhfortran/tests/compilers.py dh-fortran-0.85ubuntu2/dhfortran/tests/compilers.py
--- dh-fortran-0.85ubuntu1/dhfortran/tests/compilers.py 2026-09-02 15:38:03.000000000 +0000
+++ dh-fortran-0.85ubuntu2/dhfortran/tests/compilers.py 2026-10-02 13:38:52.000000000 +0000
@@ -26,6 +26,22 @@
1, "get_fc_flavor_arch('/bin/garbage') should fail"
+
+def test_get_fc_default_env():
+ import os
+ orig = os.environ.get("FC_DEFAULT")
+ try:
+ os.environ["FC_DEFAULT"] = "gfortran"
+ cp.get_fc_default.cache_clear()
+ assert cp.get_fc_default() == cp.default_compilers["gfortran"]
+ assert cp.which(cp.get_fc_default()) is not None
+ finally:
+ if orig is not None:
+ os.environ["FC_DEFAULT"] = orig
+ else:
+ os.environ.pop("FC_DEFAULT", None)
+ cp.get_fc_default.cache_clear()
+
def test_get_fc_default():
gf = cp.default_compilers["gfortran"]
assert cp.get_fc_default() == gf