Environment variables when cross-compiling with cgo

1,107 views
Skip to first unread message

Ian Lance Taylor

unread,
Feb 3, 2014, 6:43:38 PM2/3/14
to golang-dev, Elias Naur
https://codereview.appspot.com/57100043/ is a CL to support
cross-compiling when building programs that use cgo. It currently
introduces new environment variables XCC and XCXX to mean the
compilers to be used when cross-compiling.

Normally we only need a single compiler, which suggests that perhaps
we can always use CC. However, when running make.bash with GOARCH !=
GOHOSTARCH, we need to build some programs for GOARCH and some for
GOHOSTARCH.

The GNU autotools have many problems but they have good support for
building with a cross-compiler and for building cross-compilation
tools. They clearly differentiate between the build system (where the
tools are built), the host system (where the tools are run), and the
target system (where the programs built by the tools are run). The Go
system conflates the build and host system, for Go we have the
build/host system (where the tools are built and where they are run)
and the target system (where the programs built by the tools are run).
The build/host system is GOHOSTARCH and the target system is GOARCH.

When building a package that uses the GNU autotools, there are three
kinds of environment variables. CC is the compiler for the build
system. CC_FOR_HOST is the compiler for the host system.
CC_FOR_TARGET is the compiler for the target system.

Right now when building the Go system CC is the compiler for the
build/host system, and also becomes the default compiler for the
target system, and therefore becomes the compiler used to build the
packages that use cgo (net, os/user, crypto/x509, runtime/race). This
is of course the normal case and it should continue to work that way.

I propose that we use the same terminology as the GNU autotools, as
follows:

1) When building Go--that is, when running make.bash--CC is the
compiler used to build the Go compiler. CC_FOR_TARGET, if set,
becomes the default compiler used by cgo, and is used by cgo during
the build. If CC_FOR_TARGET is not set, it defaults to CC. In other
words, when running make.bash, CC is for GOHOSTARCH and CC_FOR_TARGET
is for GOARCH.

2) When running the go command, CC is the compiler to use. In other
words, when running go, CC is for GOARCH.

3) If we ever separate the host and build systems in Go, we will do it
by in some cases, while running make.bash, using CC_FOR_BUILD instead
of CC.

Another possibility would to always have CC correspond to GOARCH, and
to use CC_FOR_HOST while running make.bash. I personally like this
approach less because it's conventional when building a package to
have CC be the compiler used for the build.

Another possibility would be to have always have CC correspond to
GOHOSTARCH, and to use CC_FOR_TARGET when running the go command. I
personally like this approach less because the go command, unlike
make.bash, only cares about one compiler, and so I think that compiler
ought to be called CC.

Thoughts?

Ian

Dave Cheney

unread,
Feb 3, 2014, 6:48:56 PM2/3/14
to Ian Lance Taylor, golang-dev, Elias Naur
This sounds sensible. I don't have a strong opinion on the names of environment variables, all three of your suggestions are sound.

My concern is in the next 6-12 months the gc toolchain itself will find itself using version X-1 to compile version X. If new environment variables and the like are being proposed, I would like this impending use case to also be addressed.
 

Another possibility would to always have CC correspond to GOARCH, and
to use CC_FOR_HOST while running make.bash.  I personally like this
approach less because it's conventional when building a package to
have CC be the compiler used for the build.

Another possibility would be to have always have CC correspond to
GOHOSTARCH, and to use CC_FOR_TARGET when running the go command.  I
personally like this approach less because the go command, unlike
make.bash, only cares about one compiler, and so I think that compiler
ought to be called CC.

Thoughts?

Ian

--

---
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Elias Naur

unread,
Feb 3, 2014, 7:21:18 PM2/3/14
to Dave Cheney, Ian Lance Taylor, golang-dev
I assume CC_FOR_TARGET will be saved as the default CC for subsequent use of the go command.


2) When running the go command, CC is the compiler to use.  In other
words, when running go, CC is for GOARCH.

3) If we ever separate the host and build systems in Go, we will do it
by in some cases, while running make.bash, using CC_FOR_BUILD instead
of CC.


Sounds good to me.
 
My concern is in the next 6-12 months the gc toolchain itself will find itself using version X-1 to compile version X. If new environment variables and the like are being proposed, I would like this impending use case to also be addressed.

If my understanding is correct, make.bash can adjust CC and CC_FOR_TARGET before invoking version X-1 tools to build version X.
 
 

Another possibility would to always have CC correspond to GOARCH, and
to use CC_FOR_HOST while running make.bash.  I personally like this
approach less because it's conventional when building a package to
have CC be the compiler used for the build.


I think this approach is simpler, but also prefer to stick with the convention.

If you like, I'll rework my original CL to implement your preferred solution.

 - elias

Dave Cheney

unread,
Feb 3, 2014, 7:25:22 PM2/3/14
to Elias Naur, Ian Lance Taylor, golang-dev
I'm sorry, I didn't make myself clear. CC is not the system C compiler, but the version of Go minus one which is used to compile the Go based components of the current version.

Add into this picture cross compilation for additional hair pulling.

Ian Lance Taylor

unread,
Feb 3, 2014, 7:31:42 PM2/3/14
to Elias Naur, Dave Cheney, golang-dev
On Mon, Feb 3, 2014 at 4:21 PM, Elias Naur <elias...@gmail.com> wrote:
>
> On Tue, Feb 4, 2014 at 12:48 AM, Dave Cheney <da...@cheney.net> wrote:
>>
>>
>>
>>
>> On Tue, Feb 4, 2014 at 10:43 AM, Ian Lance Taylor <ia...@google.com> wrote:
>>>
>>> 1) When building Go--that is, when running make.bash--CC is the
>>> compiler used to build the Go compiler. CC_FOR_TARGET, if set,
>>> becomes the default compiler used by cgo, and is used by cgo during
>>> the build. If CC_FOR_TARGET is not set, it defaults to CC. In other
>>> words, when running make.bash, CC is for GOHOSTARCH and CC_FOR_TARGET
>>> is for GOARCH.
>
>
> I assume CC_FOR_TARGET will be saved as the default CC for subsequent use of
> the go command.

Yes.

> If you like, I'll rework my original CL to implement your preferred
> solution.

Go for it. Unless somebody thinks otherwise.

Ian

Elias Naur

unread,
Feb 5, 2014, 10:11:08 AM2/5/14
to golan...@googlegroups.com, Elias Naur, Dave Cheney
I've reworked the CL, please take a look at your convenience.

The CL leaves cgo off by default when cross compiling, so CGO_ENABLED has to be set explicitly (as well as CC_FOR_TARGET) if desired. Is that what you expected? An alternative is to always enable cgo per default, even when cross compiling, as long as CC_FOR_TARGET is set. Since CC_FOR_TARGET is only set when building Go, this requires the CGO_ENABLED setting to be saved somewhere, presumably in cmd/go/zdefaultcc.go.

 - elias

Dave Cheney

unread,
Feb 5, 2014, 3:23:30 PM2/5/14
to Elias Naur, golang-dev
This is great stuff, it will solve a major complaint by people who want to produce all their binary distributions from one system. That said, it is probably prudent to consider it experimental at this stage.

Please leave CGO disabled by default during cross compilation. That is the behaviour that users have become accustomed to. 
 
 

 - elias

Elias Naur

unread,
Feb 5, 2014, 3:49:57 PM2/5/14
to golan...@googlegroups.com, Elias Naur
I don't intend to unconditionally enable cgo during cross compilation. I only asked if cgo should default to enabled (and stay enabled for subsequent use of the go tool) when CC_FOR_TARGET is specified when make.bash is run. Defining CC_FOR_TARGET probably means that the user knows what he is doing, and that he intends to have cgo enabled.

 - elias

minux

unread,
Feb 6, 2014, 2:03:34 PM2/6/14
to Ian Lance Taylor, golang-dev, Elias Naur
Although I'm late, I still like to point out CC_FOR_TARGET is really difficult to type
and I still like the idea of XCC and XCXX.

We don't follow autotools in other aspects, so I don't think it's very important to
stick to its rules.

What's the problems for adopting XCC and XCXX? 

Ian Lance Taylor

unread,
Feb 6, 2014, 2:44:41 PM2/6/14
to minux, golang-dev, Elias Naur
I mildly prefer CC_FOR_TARGET but I would be OK with XCC if that is
what others like better. It's not like you would have to type the
name very often, though: only when building the tools the first time.

I do prefer what we have now, which is that XCC when building the go
tool becomes CC when running the go tool.

Ian
Reply all
Reply to author
Forward
0 new messages