Skip to content

configure: LTO is silently disabled whenever $CC carries a flag (every clang build on autoconf 2.73) #4792

Description

@ThalesBarretto

Summary

The LTO gate in configure.ac decides whether to add -flto from the compiler's major version:

CC_VER=`"$CC" -dumpversion 2>/dev/null | cut -f 1 -d '.'`

"$CC" is a single shell word. Whenever CC carries a flag or a wrapper, the shell tries to
execute a program literally named e.g. clang -std=gnu23, 2>/dev/null hides the
"command not found", CC_VER is empty, and configure prints

configure: not using LTO for gcc_ver=

and carries on. Nothing fails; LTO is just off.

When CC carries a flag

The root cause is the quoting, on any autoconf version: any flag or wrapper in CC
(ccache gcc, gcc -m64, a cross compiler with --sysroot=) trips it. What changed is how
often CC carries a flag without the builder putting one there:

  • autoconf 2.73's AC_PROG_CC probes for C23 and appends -std=gnu23 when the compiler does
    not default to it. Measured on autoconf 2.73: gcc (16, defaults to gnu23) stays gcc; clang
    becomes clang -std=gnu23; a user's gcc -std=gnu17 becomes gcc -std=gnu17 -std=gnu23.
  • autoconf 2.72 (Fedora 42, Debian 13) probes only C11 (c.m4 has no C23 test), so a modern
    compiler gets nothing appended and CC stays clang.

Measured

Host autoconf CC after AC_PROG_CC Gate says Build
Fedora 42, clang 20.1.8 2.72 clang building with LTO links, 76 shared objects
Arch, clang 22 2.73 clang -std=gnu23 not using LTO for gcc_ver= LTO off, silently
14 distro images, gcc 7–16 2.69–2.73 gcc on for gcc ≥ 10, off for 7/8/9 as intended

So a CC=clang configure gets LTO on autoconf-2.72 hosts (Fedora 42, Debian 13) and none on
autoconf-2.73 hosts (Arch, Tumbleweed), and nothing tells the builder. Distribution packages are
not affected: they build with gcc, whose CC is a bare word, and some add their own LTO flags
regardless (Arch's makepkg passes -flto=auto). The affected population is developers and CI jobs
that configure with clang, a wrapper such as ccache, or any flag-carrying CC. A local clang build
profile of ours had LTO off for five months before anyone noticed.

History

Fix

Drop the quotes so the shell word-splits CC, as every other use of $CC in the build already
does. One line. gcc builds are unchanged (their CC is a bare word). clang builds on autoconf
2.73 hosts regain the LTO they already get on 2.72 hosts. The "gcc 10 or above" policy and
--disable-lto are untouched. PR follows.

If the cutoff itself should ever change

The version-number probe is not the autoconf-idiomatic way to decide this. Two drop-in
alternatives were written and tested (gcc, clang, wrapper CC, a fake gcc 9, a compiler that
rejects -flto) and are kept with this issue's PR for whoever wants them:

  • Link test: AC_CACHE_CHECK + AC_LINK_IFELSE with -flto in CFLAGS/LDFLAGS. Follows
    CC through anything, covers clang, and rejects a linker without an LTO plugin at configure time
    instead of minutes into make. It would also enable LTO on gcc 7/8/9 hosts (EL8, Ubuntu 20.04,
    Leap 15.6), where it is off today by the build: add LTO as a configure option #1772 policy, so it needs an A/B on those before adoption.
  • Hybrid: the same link test guarded by the existing policy (family via __clang__, major via
    unquoted $CC -dumpversion, floor 10 for gcc only). Behaviour-preserving for gcc, adds the
    feasibility check.

Both have a property the version probe does not: a link test runs with the configure-time
CFLAGS/LDFLAGS, not the build's, and can be flipped by them — with
CFLAGS="-O2 -Wall -Wextra -Wmissing-prototypes -Werror" the probe as written declines LTO because
its own test program trips the warning, silently stripping LTO from a host that builds fine today.
That is fixable (prototype the probe function, or run it with a minimal flag set) but it is design
work, not a bug fix. The AC_CACHE_CHECK variable is safe across a CC change: autoconf aborts on a
stale cache with "'CC' has changed since the previous run".

Neither is proposed here; this issue is only about the probe not working. Cross-compiles are
unaffected by the fix: nothing runs a test program, -dumpversion is a driver query.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions