meson.is_cross_build() returning false when "cross-compiling"

Created on 26 Jul 2019  路  20Comments  路  Source: mesonbuild/meson

I'm developing on OS X, and trying to create a cross build that runs an actual GCC build (installed with homebrew), not the gcc-that's-really-clang.

So I made a basic cross-file:

[binaries]
c = '/usr/local/opt/gcc/bin/gcc-9'
cpp = '/usr/local/opt/gcc/bin/g++-9'
ar = '/usr/local/opt/gcc/bin/gcc-ar-9'

[properties]
c_args = []
c_link_args = []
cpp_args = []
cpp_link_args = []

[host_machine]
system = 'darwin'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

And invoke a cross build:

meson buildresults --cross-file=build/cross/gcc/osx-brew/gcc.txt

Meson identifies it as a cross build:

The Meson build system
Version: 0.51.999
Source dir: /Users/pjohnston/src/ea/embedded-framework
Build dir: /Users/pjohnston/src/ea/embedded-framework/buildresults
Build type: cross build
WARNING: Unknown options: "build.c_std, build.cpp_std"
Project name: Embedded Virtual Machine
Project version: 0.9
C compiler for the build machine: cc (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.4)")
C++ compiler for the build machine: c++ (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.4)")
C compiler for the host machine: /usr/local/opt/gcc/bin/gcc-9 (gcc 9.1.0 "gcc-9 (Homebrew GCC 9.1.0) 9.1.0")
C++ compiler for the host machine: /usr/local/opt/gcc/bin/g++-9 (gcc 9.1.0 "g++-9 (Homebrew GCC 9.1.0) 9.1.0")
Build machine cpu family: x86_64
Build machine cpu: x86_64

But this logic is saying we're not a cross build:

if meson.is_cross_build()
    # ...
else
    message('Since this is not a cross build, target_*_args will match native_*_args')
    # ...
endif

When I run a cross build using ARM GCC, things get detected correctly. My hunch is that my minimal definition is missing something that meson is keying off of? So I'm still exploring that aspect.

All 20 comments

I am using commit 487fdfcd1191a7a6cb4190a1fed5549c5b41b3c9

I tried a similar approach with a clang config, with similar results

# Compile code for OS X using Homebrew Clang (x86_64 variant)

[binaries]
c = '/usr/local/opt/llvm/bin/clang'
cpp = '/usr/local/opt/llvm/bin/clang++'
ar = '/usr/local/opt/llvm/bin/llvm-ar'
as = '/usr/local/opt/llvm/bin/llvm-as'
size = '/usr/local/opt/llvm/bin/llvm-size'
ld = '/usr/local/opt/llvm/bin/llvm-link'
objdump = '/usr/local/opt/llvm/bin/llvm-objdump'

[properties]
c_args = []
c_link_args = []
cpp_args = []
cpp_link_args = []

[host_machine]
system = 'darwin'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

Same result occurs.

11:52:56 {pj/cleanup} embedded-framework$ meson buildresults --cross-file=build/cross/clang/clang_x86_64.txt
The Meson build system
Version: 0.51.999
Source dir: /Users/pjohnston/src/ea/embedded-framework
Build dir: /Users/pjohnston/src/ea/embedded-framework/buildresults
Build type: cross build
WARNING: Unknown options: "build.c_std, build.cpp_std"
Project name: Embedded Virtual Machine
Project version: 0.9
C compiler for the build machine: cc (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.4)")
C++ compiler for the build machine: c++ (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.4)")
C compiler for the host machine: /usr/local/opt/llvm/bin/clang (clang 8.0.0 "clang version 8.0.0 (tags/RELEASE_800/final)")
C++ compiler for the host machine: /usr/local/opt/llvm/bin/clang++ (clang 8.0.0 "clang version 8.0.0 (tags/RELEASE_800/final)")
Build machine cpu family: x86_64
Build machine cpu: x86_64
Message: Building framework for target architecture: x86_64
Message: Native (host) applications will be built for architecture: x86_64
Message: Supplying default flags for native compiler: clang
Message: Since this is not a cross build, target_*_args will match native_*_args

Changing system, cpu_family, or cpu to something bogus caused the is_cross_build() function to return true. Is that how the logic is determined?

Unfortunately I use those values to pull in architecture-specific code...

Updated message above

There is a bug here somewhere, but why are you even using a cross file in this case? If you just want to use a different compiler you can set it with CC and CXX envvars or the native file (I _think_ it should work in this case but not 100% sure).

@jpakkane One reason to want this is that for example I have different toolchain with different libc, but I still want to build native:true targets with the system's toolchain, because system has all the dependencies I want for helper/codegen tools that are part of the build. The host only has a few basic deps, not enough for the build, that are harder to add than just using build system libraries.

Yes TheQwertiest pointed out on IRC this does look like a good use-case for the --force-cross flag I am working on.

@jpakkane I tried the flags approach but ran into problems. I will try again now that I've stabilized my builds with GCC and clang.

My original idea behind using a cross file was that the flags are an error prone way to get my users to be able to use different toolchains. A cross file and a single argument sure is a nice approach :).

Yes using cross for a native: true/false distinction is definitely the right way.

Why aren't we setting is_cross to true when a cross file is specified regardless of what target/arch is in it?

https://github.com/mesonbuild/meson/pull/5786 this is the --force-cross implementation.

I opened https://github.com/mesonbuild/meson/issues/5792 for what I think is the underlying bug here.

@Ericson2314 I understand what you're pointing out, but I just want to clarify that my perception of the bug is not:

  • Meson says that we're doing a cross build and prints that to the console
  • Then based on some logic we decided we're not really doing a cross build
  • We can't go back to change what we've printed to the console, so the build state and console output are in conflict

But rather:

  • I supplied a cross file
  • Meson sees I'm using that cross file
  • Meson determines that it's not really a cross build based on the arch/target
  • Cross file is ignored

Well regardless of perceptions, we know why meson doesn't think cross file -> cross. We don't know why it changes it's mind and doesn't think it's non-cross from the get-go.

Got it, that is indeed interesting :)

We're (Yocto Project) also hitting this. Cross-build from x86-64 to x86-64 in some form (be it to another platform, or to generate code that the build host can't execute) initially is detected as cross but once the compilers are determined and the machine names are the same reverts to native, and then the builds fail. Ditto for builds for an ARM on an ARM host.

Concrete example with a print in is_cross_build() when building on x86-64 Debian, targeting x86-64 Poky with a cross file:

| The Meson build system
| Version: 0.51.2
| Source dir: /data/poky-tmp/master/work/corei7-64-poky-linux/systemd/1_243+AUTOINC+efb536d0cb-r0/git
| Build dir: /data/poky-tmp/master/work/corei7-64-poky-linux/systemd/1_243+AUTOINC+efb536d0cb-r0/build
| is_cross_build True
| Build type: cross build
| Project name: systemd
| Project version: 243
| is_cross_build True
| C compiler for the build machine: gcc (gcc 8.3.0 "gcc (Debian 8.3.0-6) 8.3.0")
| C compiler for the host machine: x86_64-poky-linux-gcc -m64 -march=nehalem -mtune=generic -mfpmath=sse -msse4.2 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/data/poky-tmp/master/work/corei7-64-poky-linux/systemd/1_243+AUTOINC+efb536d0cb-r0/recipe-sysroot (gcc 9.2.0 "x86_64-poky-linux-gcc (GCC) 9.2.0")
| is_cross_build False

We don't know why it changes it's mind and doesn't think it's non-cross from the get-go.

Because the early machine info is for example 'linux none none' which doesn't match. It's only later when the machine infos match.

So I wrote a minimal test case for the situation where the machines match but we're passing a cross file so we should be cross: https://github.com/rossburton/meson/commit/42bd2011cb94df3ecad160477d8df5c9e5eb1763

With current master, this fails. I don't believe that there should be a --force-cross option, this should just work.

https://github.com/rossburton/meson/commit/54fb70e979f8a7573afab0af7f07ab68fe38cb65 is a very dumb change to revert is_cross_build back to being 'are there cross files?'. This fixes the dumb test case, but there's lots of other instances around the codebase like this:

is_cross = not self.machines.matches_build_machine(for_machine)

So this is not a complete fix.

I'm pretty sure this can be closed since 0b4d1e8afd5428a495f8624ee061f63977b4c268 landed.

Was this page helpful?
0 / 5 - 0 ratings