mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.39k stars 1.55k forks source link

g++ linker doesn't need -lstdc++ option by default[when use link_language: 'cpp'] #11914

Open 5741978 opened 1 year ago

5741978 commented 1 year ago

according to gcc docs: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

g++ linker doesn't need -lstdc++ option by default

but at mesonbuild/compilers/cpp.py

we can see some strange things(at line 437):

def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]:
    # We need to apply the search prefix here, as these link arguments may
    # be passed to a different compiler with a different set of default
    # search paths, such as when using Clang for C/C++ and gfortran for
    # fortran,
    search_dirs: T.List[str] = []
    for d in self.get_compiler_dirs(env, 'libraries'):
        search_dirs.append(f'-L{d}')
    return ['-lstdc++']
  1. unused search_dirs
  2. add -lstdc++ by default

the second thing additionally break static stdc++ linking if we define -static-libstdc++ in our ldflags

dcbaker commented 1 year ago

These are used and needed when using a non-c++ compiler to link code with c++ in it, like when linking c++ with rust or Fortran.

mom not sure what the right solution is here…. With msvc we have support for setting the crt through options, it may make sense to have a similar option for gcc/clang to select whether to use a static stdlib. We also don’t do a good job figuring out whether to use libc++ or libstdc++…

RomainNaour commented 11 months ago

Hello,

The missing "search_dirs" has been added recently [1] breaking at least qemu builds in Buildroot [2].

(I did a git bisect on meson to find the first bad commit [1])

The meson build system is clearly confused since it properly report libgio (2.76.1) provided by Buildroot (the one we want to link)

Run-time dependency gio-2.0 found: YES 2.76.1

but tries to link against an older version of libgio (2.66.8) leading to a link issue:

host/lib/libgio-2.0.so: undefined reference to `g_module_open_full'

The ninja build log report that paths added by "search_dirs" are before paths added by ldflags.

LINK_ARGS = -L/usr/lib/gcc/x86_64-linux-gnu/10 -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib -L/usr/lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/10/../../.. -L/lib ...

Indeed, we have two version of the glib2 library installed on the system:

[Buildroot]/host/lib/libgio-2.0.so.0.7600.1 /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.6600.8

I'm not sure why meson needs the gcc --print-search-dirs for C++ compilers.

[1] https://github.com/mesonbuild/meson/commit/59cfbf68e00aa774a9868101f423bd662938c15d [2] http://lists.busybox.net/pipermail/buildroot/2023-August/672649.html

Best regards, Romain

aduskett commented 9 months ago

Any update on how to fix this?

dcbaker commented 9 months ago

@aduskett which issue are you running into, the issue of wanting a static c++ stdlib, or the issue with the search dirs?

aduskett commented 8 months ago

@dcbaker Specifically, the search dir problem, referenced here: https://gitlab.com/buildroot.org/buildroot/-/commit/acfdf21f0b752e844a33c70a0fd2f82f4534a5a0

dcbaker commented 8 months ago

I have a patch that might help, but I can’t test it locally because the problem is basically impossible in my setup. I’m. It sure if I’ll have time to send it out before Monday, but if you don’t see it by Monday ping here again and I’ll send it out for you

dcbaker commented 8 months ago

@aduskett could you see if https://github.com/dcbaker/meson/tree/submit/gcc-stdlib-remove-system-dirs fixes your issue?

antocout commented 7 months ago

@dcbaker I tested this patch and it didn’t resolve the problem (buildroot v2023.08, meson 1.2.0, qemu v8.0.5). Indeed, this solutions does not prevent meson from searching libraries in paths presented here by @RomainNaour .

For my machine, buildroot links qemu to /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libglib-2.0.so. This path is not removed by __remove_system_dirs.