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 0.52.0 breaks cross compilation due to linker "guess" #6057

Closed
saurik opened this issue Oct 17, 2019 · 10 comments
Closed

meson 0.52.0 breaks cross compilation due to linker "guess" #6057

saurik opened this issue Oct 17, 2019 · 10 comments
Assignees
Milestone

Comments

@saurik
Copy link

saurik commented Oct 17, 2019

With meson 0.52.0, there is a new function _guess_nix_linker in environment.py that attempts to guess the linker being used; it does this by passing -Wl,--version to the compiler, but as it doesn't pass the various compiler flags added in a --cross-file, it returns the default linker for the build system instead of the chosen linker for the host system (which might be the default for a --target or might be a specific override due to -B or -fuse-ld). This worked fine with 0.51.1.

In my case, I have the following --cross-file, which uses clang from the Android NDK and overrides --target, at which point it will use a GNU linker (sometimes gold); by default, however, this version of clang will happily compile for macOS, and so will run ld64 if no arguments are passed. (FWIW, I partly include this as maybe I'm using the arguments wrong, like maybe I need to be putting these --target arguments somewhere more fundamental than merely c_args?)

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

[properties]
c_args = ['--sysroot=/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot', '-fno-addrsig', '-target', 'aarch64-unknown-linux-android21', '-gfull', '-Os', '-fdebug-prefix-map=./=', '-fdebug-prefix-map=/Users/saurik/orchid/app-android=.', '-fdata-sections', '-ffunction-sections', '-fvisibility=hidden', '-fPIC', '-I/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/include']
cpp_args = ['--sysroot=/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot', '-fno-addrsig', '-stdlib=libc++', '-target', 'aarch64-unknown-linux-android21', '-gfull', '-Os', '-fdebug-prefix-map=./=', '-fdebug-prefix-map=/Users/saurik/orchid/app-android=.', '-fdata-sections', '-ffunction-sections', '-fvisibility=hidden', '-fPIC', '-I/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/include']
objc_args = ['aarch64-unknown-linux-android21', '-gfull', '-Os', '-fdebug-prefix-map=./=', '-fdebug-prefix-map=/Users/saurik/orchid/app-android=.', '-fdata-sections', '-ffunction-sections', '-fvisibility=hidden', '-fPIC', '-I/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/include']
c_link_args = ['--sysroot=/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot', '-fno-addrsig', '-target', 'aarch64-unknown-linux-android21', '-L/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/lib']
cpp_link_args = ['--sysroot=/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot', '-fno-addrsig', '-stdlib=libc++', '-target', 'aarch64-unknown-linux-android21', '-L/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/lib']
objc_link_args = ['aarch64-unknown-linux-android21', '-L/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/lib']

[binaries]
c = '/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang'
cpp = '/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++'
objc = '-target'
ar = '/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ar'
strip = '/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-strip'
pkgconfig = '/Users/saurik/orchid/app-android/env/pkg-config'

Here is the output from meson, instrumenting the run process with RUNNING lines.

RUNNING ['cc', '-Wl,--version']
ld: unknown option: --version
clang: error: linker command failed with exit code 1 (use -v to see invocation)

C compiler for the build machine: ccache cc (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.3)")
C linker for the build machine: APPLE ld 450.3
RUNNING ['c++', '-Wl,--version']
ld: unknown option: --version
clang: error: linker command failed with exit code 1 (use -v to see invocation)

C++ compiler for the build machine: ccache c++ (clang 10.0.1 "Apple LLVM version 10.0.1 (clang-1001.0.46.3)")
C++ linker for the build machine: APPLE ld 450.3
RUNNING ['/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang', '-Wl,--version']
ld: unknown option: --version
clang: error: linker command failed with exit code 1 (use -v to see invocation)

C compiler for the host machine: /Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang (clang 8.0.7 "Android (5220042 based on r346389c) clang version 8.0.7 (https://android.googlesource.com/toolchain/clang b55f2d4ebfd35bf643d27dbca1bb228957008617) (https://android.googlesource.com/toolchain/llvm 3c393fe7a7e13b0fba4ac75a01aa683d7a5b11cd) (based on LLVM 8.0.7svn)")
C linker for the host machine: APPLE ld 450.3
RUNNING ['/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++', '-Wl,--version']
ld: unknown option: --version
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

C++ compiler for the host machine: /Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ (clang 8.0.7 "Android (5220042 based on r346389c) clang version 8.0.7 (https://android.googlesource.com/toolchain/clang b55f2d4ebfd35bf643d27dbca1bb228957008617) (https://android.googlesource.com/toolchain/llvm 3c393fe7a7e13b0fba4ac75a01aa683d7a5b11cd) (based on LLVM 8.0.7svn)")
C++ linker for the host machine: APPLE ld 450.3

The resulting issue, btw, is that I end up with Apple-specific flags being passed to my Android compiler, and Apple-specific file extensions being used for my libraries; I thereby end up with -dead_strip_dylibs (which isn't supported by this compiler, but is hilariously parsed as a kind of symbol to define and re-export) and .dylib. Here's an example LINK_ARGS from the resulting build.ninja (this is a compile of glib).

 LINK_ARGS = -L/Users/saurik/orchid/app-android/out-and/arm64-v8a/usr/lib -Wl,-dead_strip_dylibs -Wl,-undefined,error -Wl,-headerpad_max_install_names -shared -fPIC -install_name @rpath/libintl.dylib --sysroot=/Users/saurik/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -fno-addrsig -target aarch64-unknown-linux-android21
@dcbaker dcbaker added this to the 0.52.1 milestone Oct 17, 2019
@dcbaker dcbaker self-assigned this Oct 17, 2019
@dcbaker
Copy link
Member

dcbaker commented Oct 17, 2019

Not passing the arguments in the cross file to the linker detection is very certainly a bug.

dcbaker added a commit to dcbaker/meson that referenced this issue Oct 17, 2019
…linkers

There are at least two cases that we could run into here, one is someone
could use an argument -fuse-ld=...; which would cause is to misdetect
the linker being used. The other is that someone could use clang
--target=, which will cause clang to use a different linker than without
--target=; causing more mis-detection.

Fixes mesonbuild#6057
@jpakkane
Copy link
Member

jpakkane commented Nov 4, 2019

What's the status of this one? Is that branch/commit going to fix the issue or does it need more work still?

@marc-h38
Copy link
Contributor

marc-h38 commented Nov 12, 2019

it returns the default linker for the build system instead of the chosen linker for the host system (which might be the default for a --target or might be a specific override due to -B or -fuse-ld)

BTW -fuse-ld=my_linker is worse than broken with XCode 11: it does redirects /usr/bin/clang to my_linker yet keeps passing ld64 specific options like -macosx_version_min 123 or -lto_library something.dylib. Now I think you were likely not considering that particular front-end but that took me a while to realize because of the similarities.

#6063 (comment)

dcbaker added a commit to dcbaker/meson that referenced this issue Nov 13, 2019
…inker

There are at least two cases that we could run into here, one is someone
could use an argument -fuse-ld=...; which would cause is to misdetect
the linker being used. The other is that someone could use clang
--target=, which will cause clang to use a different linker than without
--target=; causing more mis-detection.

This considers environment variables, -D<lang>_args, and both cross and
native file appropriately.

This patch is very much not perfect, there's some code duplication and
some "working around the design" going on. That needs to be addressed,
but this unbreaks things, and thats good.

Fixes mesonbuild#6057
@dcbaker
Copy link
Member

dcbaker commented Nov 19, 2019

Ok, I've changed approaches and things seem to be working much better. I still need to implement the fix for windows/msvc.

@dcbaker
Copy link
Member

dcbaker commented Nov 19, 2019

and write some tests and error handling.

dcbaker added a commit to dcbaker/meson that referenced this issue Nov 19, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 20, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 20, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 20, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
@jpakkane
Copy link
Member

@saurik can you test if #6207 fixes this for you?

@dcbaker
Copy link
Member

dcbaker commented Nov 25, 2019

As a note, you can work around this right now with symlinks, clang understands that i686-linux-gnu-clang is the same as clang --target=i686-linux-gnu, for those that might be hitting this right now.

dcbaker added a commit to dcbaker/meson that referenced this issue Nov 25, 2019
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 25, 2019
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 26, 2019
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 26, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 26, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 26, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
dcbaker added a commit to dcbaker/meson that referenced this issue Nov 27, 2019
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
@nirbheek nirbheek modified the milestones: 0.52.1, 0.52.2 Nov 28, 2019
@dcbaker dcbaker modified the milestones: 0.52.2, 0.53.0 Dec 3, 2019
@dcbaker
Copy link
Member

dcbaker commented Dec 3, 2019

I've moved this from 0.52.2 to 0.53.0, as (I think) we've decided the size of the changes are too large to go into a stable release. There's a bunch of other linker related stuff in the 0.53.0 milestone now.

dcbaker added a commit to dcbaker/meson that referenced this issue Dec 12, 2019
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
scivision pushed a commit to scivision/meson that referenced this issue Dec 15, 2019
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
@ylatuya
Copy link
Contributor

ylatuya commented Dec 28, 2019

I can reproduce the same issue after upgrading to 0.52.0 that I needed for macOS Catalina fixes.
Is there any workaround to fix to miss-detection of the linker as APPLE LD ?

I tried the following workarounds:

  1. Adding ld = ['arm-linux-androideabi-ld.gold'] in the cross file [binaries]
  2. Creating a link from clang to arm-linux-androideabi-clang and using this as the c compiler in the messon cross-file.
[binaries]
c = ['/opt/android-ndk-18/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-clang', '-target', 'armv7-none-linux-androideabi19', '--sysroot', '/opt/android-ndk-18/platforms/android-19/arch-arm']
cpp = ['/opt/android-ndk-18/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++', '-target', 'armv7-none-linux-androideabi19', '--sysroot', '/opt/android-ndk-18/platforms/android-19/arch-arm']
ar = ['arm-linux-androideabi-ar']
ld = ['arm-linux-androideabi-ld.gold']
pkgconfig = 'pkg-config'
cmake = ['false']
strip = ['arm-linux-androideabi-strip']

The linker is still miss-detected as APPLE LD

@ylatuya
Copy link
Contributor

ylatuya commented Dec 28, 2019

I understand I would need #6207 to override the linker in the [binaries] section.

ylatuya added a commit to fluendo/cerbero that referenced this issue Jan 7, 2020
Linking is broken with Meson 0.52  mesonbuild/meson#6057
CLang detection for macOS Catalina's version is broken with Meson 0.49

We keep 0.52 except when targetting Android that we build for 0.49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants