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

ld: unknown option: -no_weak_imports #7204

Open
ryandesign opened this issue May 26, 2020 · 5 comments
Open

ld: unknown option: -no_weak_imports #7204

ryandesign opened this issue May 26, 2020 · 5 comments
Labels
bug OS:macos Issues specific to Apple Operating Systems like MacOS and iOS

Comments

@ryandesign
Copy link

Describe the bug
has_function fails on Mac OS X 10.6.8 (with Xcode 3.2.6) when using open source clang 9.0.1 (installed by MacPorts 2.6.2) because has_function now uses -Wl,-no_weak_imports which old linkers don't understand.

For example, at-spi2-core fails to build. The error is:

Checking for function "dlopen" : NO 
Checking for function "dlopen" : NO 

meson.build:60:2: ERROR: Problem encountered: Could not find a library with the dlopen function

dlopen exists in Mac OS X 10.3 and later so this check should not have failed.

at-spi2-core is checking for the presence of dlopen this way:

cc = meson.get_compiler('c')
if cc.has_function('dlopen')
  dl_dep = []
elif cc.has_function('dlopen', args: '-ldl')
  dl_dep = cc.find_library('dl')
else
  error('Could not find a library with the dlopen function')
endif

Looking into the meson-log.txt, the reason is:

Compiler stderr:
 ld: unknown option: -no_weak_imports
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ld is ld64 from MacPorts:

$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-127.2
configured to support archs: i386 x86_64 ppc ppc64 armv6 armv7
LTO support using: LLVM version 3.4.2

Apparently -Wl,-no_weak_imports was added to deal with an issue with Xcode 8 and later. The code in meson is using the following criteria to decide when to add the flag:

        if self.clang_type == CLANG_OSX and version_compare(self.version, '>=8.0'):
             extra_args.append('-Wl,-no_weak_imports')

This is incorrect, since it is possible and in many cases these days essential to use newer compilers on older systems to get anything built. MacPorts defaults to open source clang 9 on Mac OS X 10.6 now. Bear in mind also that open source clang and Apple clang use different version numbering schemes so you need to check which flavor of clang you've got before you check its version. I don't know what self.clang_type == CLANG_OSX is but if it was meant to verify that you've got Apple clang then it failed to do that.

Of course checking the version of Xcode would not be the correct criteria either since (on systems newer than 10.6) the user might only have the command line tools installed without having Xcode itself.

Perhaps it is the SDK version that you should be looking at but I'm not sure. Or perhaps you should check whether the linker supports -no_weak_imports before adding it.

To Reproduce
Try to install at-spi2-core on Mac OS X 10.6. For example, with MacPorts, try sudo port install at-spi2-core.

Expected behavior
Successful build

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? native
  • what operating system: Mac OS X Snow Leopard 10.6.8
  • what Python version are you using: 3.8.3
  • what meson --version: 0.54.1
  • what ninja --version if it's a Ninja build: 1.10.1
@ryandesign
Copy link
Author

I don't know what self.clang_type == CLANG_OSX is but if it was meant to verify that you've got Apple clang then it failed to do that.

Looks like this code was already changed and the condition is now:

        if isinstance(self.linker, AppleDynamicLinker) and mesonlib.version_compare(self.version, '>=8.0'):
             extra_args.append('-Wl,-no_weak_imports')

MacPorts ld64 is the Apple linker, but on older systems we install older versions of the linker presumably because there were problems getting the newer versions working properly on older systems.

@kencu
Copy link
Contributor

kencu commented May 26, 2020

you can't make any assumptions about os version and toolchain versions. It is very common for users to use updated tools. ld64-450, at least, runs on 10.6.8, for example.

and ld64 itself will accept different flags depending on the os version it is running on.

the only safe thing to do is to test if the ld64 that is in use for the build on the system you're build on accepts the flag before using it.

@dcbaker dcbaker added bug OS:macos Issues specific to Apple Operating Systems like MacOS and iOS labels May 26, 2020
@kencu
Copy link
Contributor

kencu commented May 29, 2020

Dylan, what is this part of the test meant to be testing?

mesonlib.version_compare(self.version, '>=8.0'):

If it is supposed to be testing for Xcode > 8.0, it doesn't appear to be doing that as it is hitting on all Xcodes, it seems, at least back to 3.2.6.

Is it testing for clang > 8.0 ? I doubt that it would be doing a test like that... Apple's clang is in the 1000s now.... and open source clangs from llvm are not likely on your radar to test for (and wouldn't be relevant to the linker flag anyway).

Is it testing for a linker version > 8.0? If so, then all of them pass that test, of course, as the oldest one we use is ld64-97.

@ryandesign
Copy link
Author

Ken, I assume self.version in this case is the LLVM version of the compiler. In Xcode 8 for example clang -v returns Apple LLVM version 8.0.0 (clang-800.0.38) so I assume self.version is based on that (or related internal compiler defines) and is a number like 8.0.0.

The issue was that Xcode 8 introduced the macOS 10.12 SDK which contained the clock_gettime stuff, but if you were using Xcode 8 on OS X 10.11 then has_function would answer that functions like clock_gettime were available (in the SDK) even though they weren't available on your OS version. In Xcode 8 beta 4 Apple introduced the version of ld64 that supported the -no_weak_imports flag that makes it consider only those symbols actually available on your OS version and meson wanted to use that flag if it was available.

As we've discussed in this issue, checking the LLVM version doesn't seem like a good way to determine the capabilities of the linker. It's biting us on Snow Leopard when using a newer clang with an older linker. And you pointed out that the linker accepts different flags on different OS versions which I didn't know. So I agree with you that instead meson needs to run the linker with the flag and see if the linker generates an error. If so, then the flag is not supported and should not be added to the project's flags.

@dcbaker
Copy link
Member

dcbaker commented May 29, 2020

Ken, I assume self.version in this case is the LLVM version of the compiler. In Xcode 8 for example clang -v returns Apple LLVM version 8.0.0 (clang-800.0.38) so I assume self.version is based on that (or related internal compiler defines) and is a number like 8.0.0.'

Yes, it's returning the version that clang --version (or whatever flag) returns.

I'm going to be honest that I'm not a mac developers, all I did was split the representations of the linkers and compilers into two separate classes so you could try to mix and match them. I think @ryandesign's solution is probably the right one, we do that in some other cases for the gnu-like linkers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug OS:macos Issues specific to Apple Operating Systems like MacOS and iOS
Projects
None yet
Development

No branches or pull requests

3 participants