Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meson ignores LDFLAGS when finding the linker #6377

Open
lantw44 opened this issue Dec 22, 2019 · 8 comments
Open

Meson ignores LDFLAGS when finding the linker #6377

lantw44 opened this issue Dec 22, 2019 · 8 comments
Assignees

Comments

@lantw44
Copy link
Contributor

lantw44 commented Dec 22, 2019

Describe the bug
Sometimes LDFLAGS includes options which can affect how the compiler chooses the linker. However, Meson seems to ignore LDFLAGS when determining the linker, causing wrong values to be shown when options such as -B and -fuse-ld exist in LDFLAGS.

To Reproduce
Create a dummy project:

project('dummy', 'c')

Run meson with the default environment.

$ CC='clang' meson setup ../
The Meson build system
Version: 0.52.999
Source dir: /tmp/lantw44/download/dummy
Build dir: /tmp/lantw44/download/dummy/_build
Build type: native build
Project name: dummy
Project version: undefined
C compiler for the host machine: clang (clang 8.0.1 "FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)")
C linker for the host machine: clang lld 8.0.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 0

Found ninja-1.9.0 at /usr/local/bin/ninja

Run meson with -fuse-ld option added to CC. This is OK.

$ CC='clang -fuse-ld=bfd' ~/gnome/source/meson/meson.py setup ../
The Meson build system
Version: 0.52.999
Source dir: /tmp/lantw44/download/dummy
Build dir: /tmp/lantw44/download/dummy/_build
Build type: native build
Project name: dummy
Project version: undefined
C compiler for the host machine: clang -fuse-ld=bfd (clang 8.0.1 "FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)")
C linker for the host machine: clang -fuse-ld=bfd GNU ld.bfd 2.33.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 0

Found ninja-1.9.0 at /usr/local/bin/ninja

Run meson with -fuse-ld option added to LDFLAGS. This is not OK.

$ CC='clang' LDFLAGS='-fuse-ld=bfd' ~/gnome/source/meson/meson.py setup ../
The Meson build system
Version: 0.52.999
Source dir: /tmp/lantw44/download/dummy
Build dir: /tmp/lantw44/download/dummy/_build
Build type: native build
Project name: dummy
Project version: undefined
Appending LDFLAGS from environment: ['-fuse-ld=bfd']
Appending LDFLAGS from environment: ['-fuse-ld=bfd']
C compiler for the host machine: clang (clang 8.0.1 "FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)")
C linker for the host machine: clang lld 8.0.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 0

Found ninja-1.9.0 at /usr/local/bin/ninja

You can also use -B to test the problem.

$ CC='clang -B/usr/local/bin' ~/gnome/source/meson/meson.py setup ../
The Meson build system
Version: 0.52.999
Source dir: /tmp/lantw44/download/dummy
Build dir: /tmp/lantw44/download/dummy/_build
Build type: native build
Project name: dummy
Project version: undefined
C compiler for the host machine: clang -B/usr/local/bin (clang 8.0.1 "FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)")
C linker for the host machine: clang -B/usr/local/bin GNU ld.bfd 2.33.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 0

Found ninja-1.9.0 at /usr/local/bin/ninja
$ CC='clang' LDFLAGS='-B/usr/local/bin' ~/gnome/source/meson/meson.py setup ../
The Meson build system
Version: 0.52.999
Source dir: /tmp/lantw44/download/dummy
Build dir: /tmp/lantw44/download/dummy/_build
Build type: native build
Project name: dummy
Project version: undefined
Appending LDFLAGS from environment: ['-B/usr/local/bin']
Appending LDFLAGS from environment: ['-B/usr/local/bin']
C compiler for the host machine: clang (clang 8.0.1 "FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)")
C linker for the host machine: clang lld 8.0.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 0

Found ninja-1.9.0 at /usr/local/bin/ninja

Expected behavior
Meson should show the same value regardless of how options are added. Putting -fuse-ld=bfd into either CC or LDFLAGS should make meson show GNU ld.bfd instead of the default lld.

system parameters
FreeBSD 12.1 amd64 (with clang 8.0.1 and lld 8.0.1 as the default compiler and linker), Python 3.7.5, Meson 0.52.999 (commit 7981308), Ninja 1.9.0.

GNU ld.bfd 2.33.1 is installed in /usr/local as an alternative linker.

@dcbaker
Copy link
Member

dcbaker commented Jan 7, 2020

You can put -fuse-ld=bfd into CFLAGS, and get the result you're looking for. Or in meson 0.53 (out today?) you should be able to use LD=bfd to get the same result (although in that case meson will try to set the linker for every language to bfd).

The reason that we don't look in LDFLAGS is that LDFLAGS is passed to every compiler, and passing a bogus flag -fuse-ld=bfd to dmd, for example) will result in the configure failing. the LD flag invokes code in meson to try to set the linker, or ignores it if the compiler has a set linker it must use.

This is closely related to #6413

@lantw44
Copy link
Contributor Author

lantw44 commented Jan 19, 2020

You can put -fuse-ld=bfd into CFLAGS, and get the result you're looking for.

No, CC and CFLAGS don't really work. Putting -fuse-ld there causes a lot ot has_argument and get_supported_arguments failures:

Running compile:
Working directory:  /tmp/lantw44/download/_build/meson-private/tmp4tcmu23u
Command line:  clang /tmp/lantw44/download/_build/meson-private/tmp4tcmu23u/testfile.c -o /tmp/lantw44/download/_build/meson-private/tmp4tcmu23u/output.obj -pipe -c -fuse-ld=bfd -D_FILE_OFFSET_BITS=64 -O0 -Werror=unknown-warning-option -Werror=unused-command-line-argument -Werror=ignored-optimization-argument -ffast-math 

Code:
 int i;

Compiler stdout:
 
Compiler stderr:
 clang: error: argument unused during compilation: '-fuse-ld=bfd' [-Werror,-Wunused-command-line-argument]

Compiler for C supports arguments -ffast-math: NO 

@dcbaker dcbaker self-assigned this Mar 12, 2020
@yurivict
Copy link

I have a vague memory of reporting this to libgsl ML but got no response.

This is error-prone how they have these libraries.

@jpakkane
Copy link
Member

Don't set compiler flags, use the overriding kwarg instead:

target(..., override_options: ['b_asneeded=false']

evverx added a commit to evverx/systemd that referenced this issue Apr 21, 2022
fuzz-introspector passes -fuse-ld=gold and -flto using CFLAGS/LDFLAGS and due to
mesonbuild/meson#6377 (comment) and
mesonbuild/meson#6377 it doesn't mix well with meson.
It's possible to build systemd with duct tape there using something like
google/oss-fuzz#7583 (comment) but
apparently even with gold and lto some parts of systemd are missing from
reports (presumably due to google/oss-fuzz#7598).
Let's just fail here for now to make it clear that fuzz-introspector isn't supported.
yuwata pushed a commit to systemd/systemd that referenced this issue Apr 22, 2022
fuzz-introspector passes -fuse-ld=gold and -flto using CFLAGS/LDFLAGS and due to
mesonbuild/meson#6377 (comment) and
mesonbuild/meson#6377 it doesn't mix well with meson.
It's possible to build systemd with duct tape there using something like
google/oss-fuzz#7583 (comment) but
apparently even with gold and lto some parts of systemd are missing from
reports (presumably due to google/oss-fuzz#7598).
Let's just fail here for now to make it clear that fuzz-introspector isn't supported.
@thesamesam
Copy link
Collaborator

thesamesam commented Jul 14, 2022

I think this is related to an issue I've hit today (reported by @unhappy-ending) when using a linker-specific argument (like -fuse-ld=lld and/or -Wl,--icf=full, but I think any -fuse-ld* and/or -Wl,* should work for this, as long as Clang considers it unused when invoked with -c.)

  1. -Werror=unknown-warning-option gets used
  2. Clang is called with -c which causes the linker to not be invoked
  3. Clang is being smart and is correct that e.g. -fuse-ld=lld is unused with -c, so Meson bails out

For example, with CC="clang" CFLAGS="-fuse-ld=lld -flto" ... when trying to build dev-libs/gobject-introspection-1.72.0 in Gentoo (distribution shouldn't matter here though), a snippet from build.log:

[...]
Run-time dependency gio-unix-2.0 found: YES 2.72.3
Run-time dependency libffi found: YES 3.4.2
Configuring config.h using configuration

meson.build:166:3: ERROR: C header 'Python.h' not usable

A full log can be found at /var/tmp/portage/dev-libs/gobject-introspection-1.72.0/work/gobject-introspection-1.72.0-build/meson-logs/meson-log.txt
 * ERROR: dev-libs/gobject-introspection-1.72.0::gentoo failed (configure phase):
 *   (no error message)

And from meson-log.txt:

[...]
Running compile:
Working directory:  /var/tmp/portage/dev-libs/gobject-introspection-1.72.0/work/gobject-introspection-1.72.0-build/meson-private/tmpz8zp8y7a
Command line:  clang -I/usr/include/python3.10 /var/tmp/portage/dev-libs/gobject-introspection-1.72.0/work/gobject-introspection-1.72.0-build/meson-private/tmpz8zp8y7a/testfile.c -o /var/tmp/portage/dev-libs/gobject-introspection-1.72.0/work/gobject-introspection-1.72.0-build/meson-private/tmpz8zp8y7a/output.obj -c -fuse-ld=lld -flto -ggdb3 -Werror=format-security -Werror=implicit-function-declaration -Wformat -D_FILE_OFFSET_BITS=64 -O0 -Werror=implicit-function-declaration -Werror=unknown-warning-option -Werror=unused-command-line-argument -Werror=ignored-optimization-argument

Code:

        #include <Python.h>
Compiler stdout:

Compiler stderr:
 clang-14: error: argument unused during compilation: '-fuse-ld=lld' [-Werror,-Wunused-command-line-argument]


meson.build:166:3: ERROR: C header 'Python.h' not usable

I guess there's two solutions:

  1. Clang stops being intelligent about this and warning on -c + linker args, or
  2. Meson stops using -c for configure tests even though it's technically valid for it to do so, as I think it wouldn't cause any harm to drop it (or at least doesn't pass it if it sees known linker args passed: -Wl,-* or -fuse-ld*). (A riskier approach would be to not pass -Werror=unused-compiler-argument in such a case but that would have harm, unlike not using -c.)

@eli-schwartz
Copy link
Member

In general you should not have linker args in add_project_arguments() nor in $CFLAGS.

This ticket was originally reported about passing -fuse-ld in LDFLAGS instead, which is correct and proper use of the two. This works, although meson's log status doesn't notice it in compiler/linker detection.

@thesamesam
Copy link
Collaborator

thesamesam commented Jul 14, 2022

It's hard because if setting this globally as a user, you can't get it right.

Meson is right to distinguish between CFLAGS and LDFLAGS in this way and for Meson packages, you can assume it's done correctly, but you can't in general assume LDFLAGS will be passed to the driver, and not e.g. LD directly for all packages (cheesy old Makefiles, blah blah).

I guess on our end (Gentoo's), we could possibly do some mangling of CFLAGS in meson.eclass when it contains things like this instead, as we know the handling is right already there.

@eli-schwartz
Copy link
Member

and not e.g. LD directly for all packages (cheesy old Makefiles, blah blah).

Lol, ouch.

Is it viable in this case to have those cheesy old Makefiles get hacks applied to them i.e. unset LDFLAGS? I would assume they have to be in the minority.

kasper93 added a commit to kasper93/oss-fuzz that referenced this issue Jun 18, 2024
Workarounds the issue where compile tests would fail with
`-Werror=ignored-optimization-argument` because Meson doesn't allow
linker flags in `CFLAGS` or `CXXFLAGS`.

See: mesonbuild/meson#6377 (comment)

Thanks to @evverx for the idea:
google#7583 (comment)

This is a fragile workaround, but it looks like there isn't much else we
can do.
jonathanmetzman pushed a commit to google/oss-fuzz that referenced this issue Jun 18, 2024
Workarounds the issue where compile tests would fail with
`-Werror=ignored-optimization-argument` because Meson doesn't allow
linker flags in `CFLAGS` or `CXXFLAGS`.

See:
mesonbuild/meson#6377 (comment)

Thanks to @evverx for the idea:
#7583 (comment)

This is a fragile workaround, but it looks like there isn't much else we
can do.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants