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: building cross compilers sets the default CC/CXX to whatever was built last #8161

Closed
OneOfOne opened this issue Jun 6, 2014 · 16 comments

Comments

@OneOfOne
Copy link
Contributor

OneOfOne commented Jun 6, 2014

What does 'go version' print?
go version go1.3rc1 linux/amd64
(built from tip on 2014-06-07 5:50pm CST)

What steps reproduce the problem?

1. cd $GOROOT/src
2. CC=gcc ./make.bash
3. GOOS=windows GOARCH=386 CC_FOR_TARGET=i686-w64-mingw32-gcc CGO_ENABLED=1 ./make.bash
4. go env | grep CC=

What happened?
It prints CC="i686-w64-mingw32-gcc", trying to compile a native (linux/amd64)
executable that uses cgo fails with cc1: sorry, unimplemented: 64-bit mode not compiled
in.

What should have happened instead?
It should've print CC="gcc" and GOOS=windows GOARCH=386 go env | grep CC=
should print CC="i686-w64-mingw32-gcc".

Please provide any additional information below.
Minimal example : http://play.golang.org/p/FYOPuqiZey
@ianlancetaylor
Copy link
Contributor

Comment 1:

Labels changed: added repo-main, release-go1.4.

@minux
Copy link
Member

minux commented Jun 8, 2014

Comment 2:

the essential problem is we embed only one set of CC/CXX into cmd/go.
so if you used CC_FOR_TARGET to compile Go, then without overriding CC,
the resulting cmd/go can only be used for cross compile (at least for cgo
packages).
I don't think we can embed different CC/CXX for each support platform.
we can differentiate CC/CXX settings for host and target, though.

@rsc
Copy link
Contributor

rsc commented Sep 15, 2014

Comment 3:

Labels changed: added release-go1.5, removed release-go1.4.

Status changed to Accepted.

@ianlancetaylor
Copy link
Contributor

Comment 4:

Issue #9114 has been merged into this issue.

@gordonklaus
Copy link
Contributor

Comment 5:

In reply to comment #2:  I don't see why we couldn't embed different CC/CXX for each
platform.  It appears that we are already embedding different GOGCCFLAGS for each
platform.

@minux
Copy link
Member

minux commented Dec 2, 2014

Comment 6:

we definitely can embed different CC/CXX for each platform. The devils lie in the
details.
unlike GOGCCFLAGS, which is hardcoded in cmd/go source code, C{C,XX}_FOR_TARGET
are embedded during the make.bash process because they have to provided by
the user.
Each run of make.bash can only build for one platform. Then how to manage the
accumulation of embedded CC/CXX for different platforms. Up to now, Go builds
with make.bash doesn't depend on previous builds, and that is a good virtue to
keep. Perhaps we can let the user create their own configuration file for cmd/go.
Additionally, because the current state is that each Go toolchain can only be used
for a single cross-compiled platform. Just embedding two separate sets of CC/CXX
for the host and the target seems enough.

@jsarenik
Copy link

Any ideas about how to fix this? What about starting to use prefixes like gcc?

@jsarenik
Copy link

I mean something like $(config.guess)-go...
where config.guess can stand for

  • x86_64-pc-linux-gnu
  • armv7l-unknown-linux-gnueabihf
  • ...

@jsarenik
Copy link

But this might just be an issue of the sources I am trying to compile... investigating.

@ianlancetaylor
Copy link
Contributor

We aren't going to use prefixes for the go tool.

It's not obvious to me that anything needs to change besides documentation. It's only necessary to build the go tools once. It's true that when you do that the compiler being used will be recorded. Once they are built, you can just set GOOS and GOARCH to cross-compile Go code; you don't need to run make.bash again. You do need to set CC to cross-compile C code, CXX to cross-compile C++ code, etc.

We could add a way for the go tool to map from GOOS/GOARCH to the non-Go compilers to use. But you could also write that map as a shell script that sets environment variables before invoking the go tool. And there is no obvious way to automatically populate that map.

@jsarenik
Copy link

Thanks for reply. Slowly I'm getting into it and it starts to make sense.

@mwhudson
Copy link
Contributor

We could add a way for the go tool to map from GOOS/GOARCH to the non-Go compilers to use. But you could also write that map as a shell script that sets environment variables before invoking the go tool. And there is no obvious way to automatically populate that map.

If the Go tool supported a mechanism like this, then maybe distro/OS packaging could populate this in a way that's appropriate for a given environment? Just a thought.

@anguslees
Copy link

@ianlancetaylor: I read you last comment as saying "you just need to build the go tools once, then that toolchain will automatically support all the available golang targets, just by setting GOOS/GOARCH" (but CC has to be managed yourself). Is that correct? If so, then that's great, and the ability for a single go build to support multiple targets wasn't at all clear from the "install from source" docs, nor the current structure of make.bash, which makes some attempts to set GOOS/GOARCH specifically for the intended target (not host) platform.

If my interpretation was not correct, and we do indeed need a new build of the toolchain for each host-target GOOS/GOARCH combination, then I'm still confused how that should be managed without some sort of per-target executable prefix or install location.

I'm currently in the middle of trying to build an amd64->arm go1.6 cross toolchain within an openembedded recipe and finding it much harder than I expected, not being familiar with the internals of the go toolchain. More sagely advice sought.

@ianlancetaylor
Copy link
Contributor

In general, discussion should probably move off this issue and into a forum. See https://golang.org/wiki/Questions. Thanks.

It is true today, but was not always true, that once you have built the Go tools for one system, you only need to set GOOS/GOARCH to build Go programs for a different system. I agree that the documentation has not entirely caught up with the source code.

@OneOfOne
Copy link
Contributor Author

Sorry for the extra comment but this might help people looking at this issue:

To compile for a supported os/arch all you need to do is just to run:

env GOOS=os GOARCH=arch go build
#eg
env GOOS=linux GOARCH=arm64 go build
# or to support cgo:
# install gcc for your target, depends on the distro then for example for arm:
env CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=arm-eabi-gcc go build

That's all you have to do, nothing else.

@anguslees

@gopherbot
Copy link

Change https://golang.org/cl/76018 mentions this issue: cmd/dist, cmd/cgo, cmd/go: allow per-goos/goarch default CC

@golang golang locked and limited conversation to collaborators Nov 6, 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

10 participants