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

cmd/go: how to pass -mmacosx-version-min=10.8 from cmd/go down to MacOS clang? #18400

Closed
akamensky opened this issue Dec 21, 2016 · 12 comments
Closed

Comments

@akamensky
Copy link

akamensky commented Dec 21, 2016

Please answer these questions before submitting your issue. Thanks!

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

go version go1.7.4 darwin/amd64

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

MacOS 10.12.2

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH=""
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/rk/g9b46vzx70g86vhvqtmwtjxw0000gn/T/go-build661102909=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"

What did you do?

Build a static library to be used in another project:
GOPATH=$(pwd) go install -buildmode=c-archive main
Then try to use that library in a Qt5.7 project.

What did you expect to see?

Main QTt5.7 projects builds successfully

What did you see instead?

The project build fails, because apparently the MacOS clang by default will compile with compatibility to latest OS version.

libmain.a(000000.o)) was built for newer OSX version (10.12) than being linked (10.8)

COMMENT

It is possible to specify a compatibility version when using MacOS clang++. For example here is how Qt does it with -mmacosx-version-min flag:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -headerpad_max_install_names -stdlib=libc++ -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -mmacosx-version-min=10.8 -Wl,-rpath,/Users/username/Qt5.7.1/5.7/clang_64/lib -o <redacted>

However I seem to be unable to pass ANY CFLAGS as then the build script dies:

$ CFLAGS="-mmacosx-version-min=10.8" GOPATH=/Users/username/IdeaProjects/eswift-client go install -x -buildmode=c-archive main
WORK=/var/folders/rk/g9b46vzx70g86vhvqtmwtjxw0000gn/T/go-build609762181
$ 
@bradfitz
Copy link
Contributor

What makes you think it died?

It looks like it just decided there was no work to do.

(Probably because the CFLAGS environment variable doesn't affect Go and/or is not part of Go's buildid signature.)

Have you tried Go's -extldflags flags? See https://golang.org/pkg/cmd/link/

I think this will work if you use the right arguments.

@akamensky
Copy link
Author

@bradfitz -extldflags are passed during the linking time, it is not passed during compile time. The compatibility mark is set compile-time AFAIK.

@akamensky
Copy link
Author

akamensky commented Dec 21, 2016

@bradfitz
Wow, that is really fast closing issue without even reading into details. The report is not that process died, the report is that there is no way to set compatibility mark (yes I tried -extldflags, but again those are passed to linked; it is clang again just by conincidence, with gcc it would be gcc/g++ and ld)

@akamensky
Copy link
Author

@bradfitz Moreover go build same as go install does not have -extldflags. It has -ldflags, but then it tries to use go link as linked which fails (because the buildmode is set ti c-archive)

@bradfitz
Copy link
Contributor

Does go {build,install} -ldflags=-extldflags=-mmacosx-version-min=10.8 your/go/cmd not work?

@akamensky
Copy link
Author

akamensky commented Dec 21, 2016

@bradfitz No. The library still compiled as minimum version 10.12 compatible

With -x it shows /usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/cinterface/_obj/exe/a.out.a -L $WORK -L /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64 -extld=clang -buildmode=c-archive -buildid=50ff8b062a12a6887dcebe054e651e2b348418e6 -extldflags=-mmacosx-version-min=10.8 $WORK/cinterface.a as command, but does not show underlying clang command...

@bradfitz
Copy link
Contributor

Delete your target binary and re-run the go build command with all those flags, but also include -x to print the output. Is it actually running what you expect?

@akamensky
Copy link
Author

Updated the comment, I always use -x to see full output. And of course I deleted pkg/ before doing that.

Below is full output. It passes -extldflags to go link, but the final .a is still 10.12 only (also even with -x it does not show clang linking call)

[alexey.kamenskiy@nc-macbook:eswift-client]$ CFLAGS="-mmacosx-version-min=10.8" GOPATH=/Users/alexey.kamenskiy/IdeaProjects/eswift-client go install -x -buildmode=c-archive -ldflags="-extldflags=-mmacosx-version-min=10.8" cinterface
WORK=/var/folders/rk/g9b46vzx70g86vhvqtmwtjxw0000gn/T/go-build680834420
mkdir -p $WORK/cinterface/_obj/
mkdir -p $WORK/cinterface/_obj/exe/
cd /Users/alexey.kamenskiy/IdeaProjects/eswift-client/src/cinterface
CGO_LDFLAGS="-g" "-O2" /usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/cinterface/_obj/ -importpath cinterface -exportheader=$WORK/cinterface/_obj/_cgo_install.h -- -I $WORK/cinterface/_obj/ main.go
cd $WORK
clang -fdebug-prefix-map=a=b -c trivial.c
clang -gno-record-gcc-switches -c trivial.c
cd /Users/alexey.kamenskiy/IdeaProjects/eswift-client/src/cinterface
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/cinterface/_obj/ -g -O2 -o $WORK/cinterface/_obj/_cgo_main.o -c $WORK/cinterface/_obj/_cgo_main.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/cinterface/_obj/ -g -O2 -o $WORK/cinterface/_obj/_cgo_export.o -c $WORK/cinterface/_obj/_cgo_export.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/cinterface/_obj/ -g -O2 -o $WORK/cinterface/_obj/main.cgo2.o -c $WORK/cinterface/_obj/main.cgo2.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -o $WORK/cinterface/_obj/_cgo_.o $WORK/cinterface/_obj/_cgo_main.o $WORK/cinterface/_obj/_cgo_export.o $WORK/cinterface/_obj/main.cgo2.o -g -O2
/usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/cinterface/_obj/ -dynpackage main -dynimport $WORK/cinterface/_obj/_cgo_.o -dynout $WORK/cinterface/_obj/_cgo_import.go
cd $WORK
clang -no-pie -c trivial.c
cd /Users/alexey.kamenskiy/IdeaProjects/eswift-client/src/cinterface
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -o $WORK/cinterface/_obj/_all.o $WORK/cinterface/_obj/_cgo_export.o $WORK/cinterface/_obj/main.cgo2.o -g -O2 -Wl,-r -nostdlib
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/cinterface.a -trimpath $WORK -p main -buildid 50ff8b062a12a6887dcebe054e651e2b348418e6 -D _/Users/alexey.kamenskiy/IdeaProjects/eswift-client/src/cinterface -I $WORK -I /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64 -pack $WORK/cinterface/_obj/_cgo_gotypes.go $WORK/cinterface/_obj/main.cgo1.go $WORK/cinterface/_obj/_cgo_import.go
pack r $WORK/cinterface.a $WORK/cinterface/_obj/_all.o # internal
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/cinterface/_obj/exe/a.out.a -L $WORK -L /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64 -extld=clang -buildmode=c-archive -buildid=50ff8b062a12a6887dcebe054e651e2b348418e6 -extldflags=-mmacosx-version-min=10.8 $WORK/cinterface.a
mkdir -p /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64/
mv $WORK/cinterface/_obj/_cgo_install.h /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64/cinterface.h
mv $WORK/cinterface/_obj/exe/a.out.a /Users/alexey.kamenskiy/IdeaProjects/eswift-client/pkg/darwin_amd64/cinterface.a
[alexey.kamenskiy@nc-macbook:eswift-client]$

@bradfitz
Copy link
Contributor

And of course I deleted pkg/ before doing that.

The output from the linker doesn't go in pkg/, it goes to your $GOPATH/bin or $GOBIN.

Anyway, I'll reopen this and let @ianlancetaylor decide whether there's a bug. If anything, the bug is that our pkg directory causes confusion and needs to be replaced with a proper cache. That is #4719.

@bradfitz bradfitz reopened this Dec 21, 2016
@bradfitz bradfitz changed the title MacOS clang by default marks resulting output as only latest MacOS compatible cmd/go: how to pass linker flags from cmd/go down to MacOS clang? Dec 21, 2016
@minux
Copy link
Member

minux commented Dec 21, 2016 via email

@ianlancetaylor
Copy link
Contributor

You can use -ldflags="-v -extldflags=-mmacosx-version-min=10.8" (I added -v) to see exactly how the Go linker invokes the clang linker. Certainly the -extldflags option should be being passed to clang.

The Go linker also invokes dsymutil on Darwin. Perhaps that is the problem here. Try invoking the go tool with -ldflags=-s to see if that makes a difference.

@rsc
Copy link
Contributor

rsc commented Jan 4, 2017

CGO_CFLAGS=-mmacosx-version-min=10.8 CGO_LDFLAGS=-mmacosx-version-min=10.8 should suffice. In fact only the CGO_CFLAGS is really needed, but setting the CGO_LDFLAGS lets you see a link error if you add -ldflags -v to the go command:

$ cat x.go
package main

import "C"

//export GoHello
func GoHello() {
	println("hello")
}

func main() {}

$ CGO_CFLAGS=-mmacosx-version-min=10.8 \
  CGO_LDFLAGS=-mmacosx-version-min=10.8 \
  go build -ldflags -v x.go

...
ld: warning: object file (/var/folders/qk/vp4mp_hj5qlb_1_w97rgqc4r000n9d/T/go-link-038149023/000001.o) was built for newer OSX version (10.12) than being linked (10.8)
...
$

The reason this is happening is that there are .o files in the standard library that were not compiled with this CGO_CFLAGS setting, and they are being linked into the binary too. To force rebuilding of everything, the best approach (the one that works with go install as well) is to use a custom installsuffix, which keeps those build artifacts separate from the normal ones:

$ CGO_CFLAGS=-mmacosx-version-min=10.8 \
  CGO_LDFLAGS=-mmacosx-version-min=10.8 \
  go build -installsuffix qt -ldflags -v x.go

...
...no warning here...
...
$

Sorry for the confusion. I expect that a future version of cmd/go that is more careful about reuse of compiled archives will end up recompiling even the standard library automatically when you set CGO_CFLAGS this way, making -installsuffix unneccessary. But for now, that's the best workaround.

@rsc rsc changed the title cmd/go: how to pass linker flags from cmd/go down to MacOS clang? cmd/go: how to pass -mmacosx-version-min=10.8 from cmd/go down to MacOS clang? Jan 4, 2017
@rsc rsc closed this as completed Jan 4, 2017
@golang golang locked and limited conversation to collaborators Jan 4, 2018
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

6 participants