build: fix host toolchain detection on a host whose CC carries flags - #1042
build: fix host toolchain detection on a host whose CC carries flags#1042metaneutrons wants to merge 1 commit into
Conversation
4de208c to
a57718f
Compare
Two independent faults stop the host side of the build on a current
macOS/clang host. Both are in code that derives tool names or flags from
another variable, and both are silent: configure reports success and the
failure surfaces much later as a missing program.
configure.in derives the host binutils names from $CC_BASE, and guards
that derivation with a test against "gcc". CC_BASE is a whole command
line rather than a program name, because AC_PROG_CC leaves the standard
flag it selected in CC - "gcc -std=gnu23", not "gcc". Reading
configure.in alone makes that look impossible, since CC_BASE=$CC comes
before the AC_PROG_CC_STDC call; the generated configure shows why it is
not, with
CC="$CC $ac_cv_prog_cc_c23"
several hundred lines above CC_BASE=$CC. AC_PROG_CC_STDC has been
obsolete since autoconf 2.70 and does nothing here; AC_PROG_CC does the
standard detection itself.
So the guard always takes the non-gcc path, and the names come out of the
command line rather than the program: HOST_AR becomes "cr", which is ar's
flags, and the build later dies with
gmake[3]: cr: No such file or directory
while configure had reported no problem at all. Fixed by deriving the
program name first and testing and substituting that.
config/make-autotools.tmpl passes CXXCPP="$(HOST_CPP)" to the autotools
ports built for the host. HOST_CPP is the C preprocessor, and a port that
probes for a C++ preprocessor rejects it:
checking how to run the C++ preprocessor... gcc -std=gnu23 -E
configure: error: C++ preprocessor "gcc -std=gnu23 -E" fails sanity check
gmp is the first to hit it. Fixed by deriving CXXCPP from HOST_CXX.
Tested on darwin-aarch64 building raspi-aarch64. What decides whether the
first fault appears is not the host OS but whether the compiler needs an
explicit -std flag to reach the standard autoconf asks for: clang does,
so the flag lands in CC; gcc 15 and newer already default to gnu23, so
$ac_cv_prog_cc_c23 stays empty and CC keeps its bare name. That predicts
the fault on Linux with an older gcc as well, and a second pair of eyes
there would be welcome.
a57718f to
6387704
Compare
|
Thanks for the detailed write-up. The cr: No such file or directory failure is real, and the trace through AC_PROG_CC leaving -std=gnu23 in CC is a genuinely useful find. I think the root cause is a little different from the one described, though, and it points at a smaller fix. Autoconf already strips the flag for us. AC_PATH_PROG(CC,$CC) (configure.in:150) expands to: Extract the first word of "$CC", so it can be a program name with args.set dummy $CC; ac_word=$2 So by the time the family detection runs, CC is the resolved path with the flag dropped. That is why the HOST_COMPILER_VERSION probe, which runs "$CC" --version, still works in exactly the scenario described. The flag-free program name that CC_PROG derives by hand is already available as $CC; the patch re-derives it from the older CC_BASE snapshot instead. The name test is the part that is actually wrong. config/features.in:1591 does the same classification without consulting the compiler's name at all: COMPILER_VERSION= configure.in already computes HOST_COMPILER_VERSION the same way, and then second-guesses it with test "$CC_BASE" != "gcc". That extra name check is what breaks, and it stays fragile after the patch: CC_PROG is not "gcc" for gcc-13, /usr/bin/gcc-13, cc, or ccache gcc, which yields ccache. On any host whose compiler reports clang, those still take the LLVM branch and still build an llvm-ar name with a bogus suffix. On HOST_AR becoming cr: the cr is not ar's flags leaking in, it is part of the intended value. configure.in:625 builds it deliberately: base_ar_name=${HOST_TOOLCHAIN_PREFIX}ar${HOST_TOOLCHAIN_SUFFIX} The target side uses the same convention, where AR is the ar program followed by cr. What goes wrong is that AROS_PROG finds nothing for a garbage base_ar_name, so AR_BASE is empty, the string becomes " cr", and the sed has nothing to substitute. That also explains the "configure reports success" part, which I think is worth splitting out as its own issue. AROS_REQUIRED (acinclude.m4:9) only rejects an empty value and "no", so " cr" passes the check. It guards every host tool the same way, so any similar mis-derivation will keep surfacing at build time rather than at configure time. Suggested direction, if it is useful: drop the name-based test and classify purely from HOST_COMPILER_VERSION, as features.in does. The LLVM branch then needs another way to get its suffix, which is the real problem hiding here. Where a program name genuinely is needed, $CC after AC_PATH_PROG already provides it. Tightening AROS_REQUIRED or AROS_PROG to check that the first word is executable would also catch this class of failure while configuring. Two smaller notes: the configure hunk duplicates the configure.in change by hand, so it would be better regenerated, and the remaining CC_BASE uses at configure.in:3225, 3232 and 3240 mean the stated root cause is still present after the change. |
Two independent faults stop the host side of the build on a current macOS/clang host. Both derive a tool name or flag from another variable, and both are silent — configure reports success and the failure surfaces much later as a missing program.
configure.inderives the host binutils names from$CC_BASEand guards that with a test against"gcc".CC_BASEis a whole command line rather than a program name, becauseAC_PROG_CCleaves the standard flag it selected inCC(gcc -std=gnu23). Readingconfigure.inalone makes that look impossible, sinceCC_BASE=$CCcomes before theAC_PROG_CC_STDCcall; the generatedconfigureshows why it is not:AC_PROG_CC_STDChas been obsolete since autoconf 2.70 and does nothing here;AC_PROG_CCdoes the standard detection itself, well beforeCC_BASEcaptures the value.So the guard always takes the non-gcc path, the names come from the command line rather than the program,
HOST_ARbecomescr— which isar's flags — and the build later dies withwhile configure had reported nothing wrong. Fixed by deriving the program name first, then testing and substituting that.
config/make-autotools.tmplpassesCXXCPP="$(HOST_CPP)"to the autotools ports built for the host.HOST_CPPis the C preprocessor, and a port probing for a C++ one rejects it:gmp is the first to hit it. Fixed by deriving
CXXCPPfromHOST_CXX.Testing
Tested on
darwin-aarch64buildingraspi-aarch64.What decides whether the first fault appears is not the host OS but whether the compiler needs an explicit
-std=flag to reach the standard autoconf asks for. clang does, so the flag lands inCC. gcc 15 and newer already default to gnu23, so$ac_cv_prog_cc_c23stays empty andCCkeeps its bare name. That predicts the fault on Linux with an older gcc too, and a second pair of eyes there would be welcome before this is merged. Draft because of that gap, not because the change is unfinished.Not fixed here
The same pattern sits in three more places, where a tool prefix is prepended to what may be a whole command line rather than a program name:
With
gcc -std=gnu23those happen to produce a working command. With a path inCCthey producearm-aros-/usr/bin/gcc-13. Left alone deliberately, to keep this change to the two faults that actually break the build.Note on squashing
The two fixes are logically separate and were developed as separate commits. They are squashed here as one "make the host build work" change; happy to split them if a reviewer prefers one bug per commit.