Skip to content

Prefer $GCC_AR over $AR with gcc? #13324

Open

Description

@QuLogic

Describe the bug
When compiling with LTO on gcc, it is necessary to use gcc-ar instead of ar, as the latter doesn't have the linker plugin enabled. Meson thus looks for it preferentially if using gcc:

elif compiler.id == 'gcc':
# Use gcc-ar if available; needed for LTO
trials = [defaults['gcc_static_linker']] + default_linkers

However, when looking for the static linker, Meson looks in $AR first.

With the conda-forge compilers, they set AR=/path/to/env/bin/x86_64-conda-linux-gnu-ar and GCC_AR=/path/to/env/bin/x86_64-conda-linux-gnu-gcc-ar. This means that Meson will find the static linker without the LTO linker plugin. Because the linker just emits the missing plugin as a warning, this will either cause executables to fail building with missing symbols, or worse, shared libraries to build fine, but then not load with mysterious errors.

I know that I can myself set AR=$GCC_AR, but when building a Python package with LTO enabled by default (as we do in Matplotlib since before using Meson), the problem is quite buried and annoying to explain to new developers, and it'd be nice if Meson just worked correctly out-of-the-box.

So I wonder if Meson should (if using gcc) check GCC_AR first? I don't know how standard this environment variable is, but that's what they seem to be using.

To Reproduce
In this case, I use one of the test cases with static libraries, and enable LTO:

$ micromamba create -n meson-gcc-ar -c conda-forge meson compilers
$ micromamba activate meson-gcc-ar
$ meson setup -Db_lto=true test\ cases/common/5\ linkstatic/ work\ area
$ ninja -C work\ area/
ninja: Entering directory `work area/'
[6/7] Linking static target libmylib.a
/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-ar: libmylib.a.p/libfile.c.o: plugin needed to handle lto object
[7/7] Linking target prog
FAILED: prog 
/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-cc  -o prog prog.p/main.c.o -L/home/elliott/micromamba/envs/meson-gcc-ar/lib -flto -Wl,--as-needed -Wl,--no-undefined -Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,--allow-shlib-undefined -Wl,-rpath,/home/elliott/micromamba/envs/meson-gcc-ar/lib -Wl,-rpath-link,/home/elliott/micromamba/envs/meson-gcc-ar/lib -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /home/elliott/micromamba/envs/meson-gcc-ar/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /home/elliott/micromamba/envs/meson-gcc-ar/include libmylib.a
/home/elliott/micromamba/envs/meson-gcc-ar/bin/../lib/gcc/x86_64-conda-linux-gnu/12.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /tmp/cciBMYVO.ltrans0.ltrans.o: in function `main':
/home/elliott/code/meson/work area/<artificial>:4: undefined reference to `func'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Expected behavior
When LTO is enabled using the conda-forge compilers, the build succeeds.

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? Native
  • what operating system (e.g. MacOS Catalina, Windows 10, CentOS 8.0, Ubuntu 18.04, etc.): Fedora 40
  • what Python version are you using: 3.12.3
  • what meson --version: 1.4.0
  • what ninja --version if it's a Ninja build: 1.12.1

Activity

  1. QuLogic commented on Jun 15, 2024

    @QuLogic
    MemberAuthor

    Also perhaps of note is that the conda-forge package sets CMAKE_ARGS as:

    -DCMAKE_AR=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-ar
    -DCMAKE_CXX_COMPILER_AR=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-gcc-ar
    -DCMAKE_C_COMPILER_AR=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-gcc-ar
    -DCMAKE_RANLIB=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-ranlib
    -DCMAKE_CXX_COMPILER_RANLIB=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-gcc-ranlib
    -DCMAKE_C_COMPILER_RANLIB=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-gcc-ranlib
    -DCMAKE_LINKER=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-ld
    -DCMAKE_STRIP=/home/elliott/micromamba/envs/meson-gcc-ar/bin/x86_64-conda-linux-gnu-strip
    -DCMAKE_BUILD_TYPE=Release
    

    I don't know how CMake works, but I guess it picks these CMAKE_<lang>_COMPILER_AR variables over the CMAKE_AR variable, giving it the gcc-ar variant.

  2. eli-schwartz commented on Jun 16, 2024

    @eli-schwartz
    Member

    Setting an environment variable usually means you definitely absolutely want to use it. Of course if you also define something else in a native file then that takes precedence.

    I'm hesitant to start looking at an environment variable such as $GCC_AR which I've never heard of before and seems like it may be specific to conda-forge. It's not clear to me what is supposed to read this anyway.

    Do you happen to know why the two are defined differently?

  3. QuLogic commented on Jun 17, 2024

    @QuLogic
    MemberAuthor

    I don't know why it's set that way, only that it is and it makes it so that things don't work out-of-the-box.

    @jakirkham do you know why there's this separate $GCC_AR, or who to ask about it?

  4. jakirkham commented on Jun 24, 2024

    @jakirkham
  5. self-assigned this
    on May 15, 2025
  6. thesamesam commented on May 15, 2025

    @thesamesam
    Member

    I was looking into this for the benefit of autoconf and automake then came across this bug in Meson, and found we seem to do the right thing if everything is unset indeed.

    I find it hard for us to justify ignoring AR if set in the environment, if it's being set to something which doesn't do the right thing. What're you proposing we do here?

    EDIT: But maybe we can view it a bit differently in the context of cross and machine files, where people may set ar trying to do the right thing, like in https://embeddedartistry.com/blog/2020/04/13/prefer-gcc-ar-to-ar-in-your-buildsystems/.

    EDIT 2: I see you mentioned GCC_AR now, oops. But that won't help the cross case, and I don't think it's a standard variable.

  7. thesamesam commented on Nov 10, 2025

    @thesamesam
    Member

    Somewhat related to #8831 and definitely #1646.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions