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

Fails to compile on macOS 10.12 with no_weak_imports. #16770

Closed
DomT4 opened this issue Aug 17, 2016 · 4 comments
Closed

Fails to compile on macOS 10.12 with no_weak_imports. #16770

DomT4 opened this issue Aug 17, 2016 · 4 comments

Comments

@DomT4
Copy link

DomT4 commented Aug 17, 2016

  1. What version of Go are you using (go version)?

1.7

  1. What operating system and processor architecture are you using (go env)?

MacOS Sierra/10.12, amd64.

  1. What did you do?

An Apple engineer recommends appending -Wl,-no_weak_imports to LDFLAGS where Xcode 8 is present to resolve issues such as this. Following that advice yields build failure for Go 1.7:

# crypto/x509
ld: weak import of symbol '_SecCertificateCopyNormalizedIssuerContent' not supported because of option: -no_weak_imports for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Build logs are here. The build was performed inside Homebrew, but reproduces outside of Homebrew using the recommend LDFLAG as well, at least in my VM.

@achivetta
Copy link

Here's what I think is happening here. Go builds go/src/crypto/x509/root_cgo_darwin.go with:

-mmacosx-version-min=10.6

This means that any code added after 10.6 gets a weak link. That's (one of) the things that the new linker flag disallows.

If I'm understanding the Go code correctly, it makes sense that Go does this because (a) it is building content that it'll static link into the binaries it produces, which should deploy back to 10.6 and (b) it has a check before its use of SecCertificateCopyNormalizedIssuerContent to fallback to an older path on older OS, which is the correct way to use a weak link.

In general, disallowing weak links in homebrew makes sense because you are building software to run on the current machine and by-far most software homebrew builds isn't expecting weak link behavior. But, building what's essentially a compiler runtime isn't one of those cases. I think homebrew will have to opt go out of this behavior.

(For context, the goal of -no_weak_imports is to improve the case that you are building software to run on the exact minimum deployment target you specify by moving runtime errors to compile time, where autoconf and/or the developer/packager can deal with them. Go (correctly) setting an old target subverts that.)

tdsmith added a commit to tdsmith/brew that referenced this issue Aug 18, 2016
Issue Homebrew/homebrew-core#3727 suggested we set -no_weak_imports for
new versions of Xcode to ensure that e.g. building on 10.11 against the
10.12 SDK doesn't result in a situation where autotools thinks symbols
exist that don't actually exist on the current platform.

Further discussion in golang/go#16770 revealed that some packages
require weak imports to build normally.
@DomT4
Copy link
Author

DomT4 commented Aug 19, 2016

We've worked around this in Homebrew by selectively disabling the flag, but will leave this open to see if there's anything actionable here as far as the golang team are concerned. Any Homebrew user impacted should brew update & you'll be able to install go fine again.

@mcphailtom
Copy link

mcphailtom commented Aug 20, 2016

@achivetta I'm wondering if you may be able to enlighten me a little, I understand the concept of weak imports however I'm wondering how (or even if) the target SDK/OS of go affects the build targets of packages subsequently built with that built version? 😕

I encountered the same weak imports issue with the delve package go-delve/homebrew-delve#2

Nowhere in the delve makefiles could I find reference to the -mmacosx-version-min= which leads me to assume that it is defaulted to the target of the build of go used to build it?

I feel 😖 just writing that.... The solution works perfectly I'm just hoping to understand the workings behind it a little better.

@quentinmit
Copy link
Contributor

It sounds like this is WAI from Go's perspective; we correctly use weak linking.

@mcphailtom The target SDK affects the features that Go will potentially use; anything newer than the target SDK will not be used. That said, Go itself doesn't use much from the SDK, so in practice you won't find much affected by this. Also, depending on how you set the target SDK version, that might not even be baked into Go, so packages compiled later would use whatever SDK you had at that time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants