Package: meson
Version: 0.48.1-1
User: helm...@debian.org
Usertags: rebootstrap

Meson wrongly caches the result of a dependency() call. If you need a
dependency for both the build architecture and host architecture, meson
caches uses the results from the first invocation for the other
invocation. Let me demonstrate the faulty behaviour with the following
meson file:


    project('test', 'c')
    # The following dependency call is unnecessary here, but its results
    # leak into the next call.
    glib = dependency('glib-2.0')
    native_glib = dependency('glib-2.0', native: true)
    gen = executable('gen', 'gen.c', dependencies: [native_glib], native: true)
    out = custom_target('out', output: 'out', command: [gen], capture: true, 
build_by_default: true)

To actually build it, you need some gen.c file:

    #include <stdio.h>
    int main() { printf("success\n"); return 0; }

When cross building this project, the expected behaviour is generating a
file called "out" with the "content" success". To reproduce, create a
crossfile using /usr/share/meson/debcrossgen e.g. for ppc64el. Then
running meson yields the following output:

| WARNING: Unknown CPU family 'powerpc64le', please report this at 
https://github.com/mesonbuild/meson/issues/new
| The Meson build system
| Version: 0.48.1
| Source dir: .../source
| Build dir: .../source/build
| Build type: cross build
| Project name: test
| Project version: undefined
| Native C compiler: cc (gcc 8.2.0 "cc (Debian 8.2.0-9) 8.2.0")
| Cross C compiler: /usr/bin/powerpc64le-linux-gnu-gcc (gcc 8.2.0)
| Host machine cpu family: powerpc64le
| Host machine cpu: ppc64el
| Target machine cpu family: powerpc64le
| Target machine cpu: ppc64el
| Build machine cpu family: x86_64
| Build machine cpu: x86_64
| Cross dependency glib-2.0 found: YES 2.58.1
| Native dependency glib-2.0 found: YES 2.58.1
| Build targets in project: 2
| Found ninja-1.8.2 at /usr/bin/ninja

All looks well. Now run ninja -v.

| [1/3] cc -Igen@exe -I. -I.. -I/usr/include/glib-2.0 
-I/usr/lib/powerpc64le-linux-gnu/glib-2.0/include -fdiagnostics-color=always 
-pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -g  -MD -MQ 'gen@exe/gen.c.o' 
-MF 'gen@exe/gen.c.o.d' -o 'gen@exe/gen.c.o' -c ../gen.c
| [2/3] cc  -o gen 'gen@exe/gen.c.o' -Wl,--no-undefined -Wl,--as-needed 
-Wl,--start-group /usr/lib/powerpc64le-linux-gnu/libglib-2.0.so -Wl,--end-group 
'-Wl,-rpath,$ORIGIN/../../usr/lib/powerpc64le-linux-gnu' 
-Wl,-rpath-link,/usr/lib/powerpc64le-linux-gnu
| FAILED: gen
| cc  -o gen 'gen@exe/gen.c.o' -Wl,--no-undefined -Wl,--as-needed 
-Wl,--start-group /usr/lib/powerpc64le-linux-gnu/libglib-2.0.so -Wl,--end-group 
'-Wl,-rpath,$ORIGIN/../../usr/lib/powerpc64le-linux-gnu' 
-Wl,-rpath-link,/usr/lib/powerpc64le-linux-gnu
| /usr/bin/ld: /usr/lib/powerpc64le-linux-gnu/libglib-2.0.so: error adding 
symbols: file in wrong format
| collect2: error: ld returned 1 exit status
| ninja: build stopped: subcommand failed.

You notice that the native compiler invocation is asked to link the host
architecture libglib-2.0.so. That's wrong.

To see that this is actually the first depenency() call leaking into the
next call, we can simply remove the first (unnecessary) call. After
doing so, the sample project crosses fine.

Helmut

Reply via email to