mirror of
https://github.com/golang/go
synced 2024-11-23 09:30:03 -07:00
cmd/go, cmd/cgo, make.bash: cross compiling with cgo enabled
Introduce two new environment variables, CC_FOR_TARGET and CXX_FOR_TARGET. CC_FOR_TARGET defaults to CC and is used when compiling for GOARCH, while CC remains for compiling for GOHOSTARCH. CXX_FOR_TARGET defaults to CXX and is used when compiling C++ code for GOARCH. CGO_ENABLED defaults to disabled when cross compiling and has to be explicitly enabled. Update #4714 LGTM=minux.ma, iant R=golang-codereviews, minux.ma, iant, rsc, dominik.honnef CC=golang-codereviews https://golang.org/cl/57100043
This commit is contained in:
parent
76c9182523
commit
2dc759d7c6
3
src/cmd/dist/a.h
vendored
3
src/cmd/dist/a.h
vendored
@ -75,7 +75,8 @@ extern char *goroot_final;
|
|||||||
extern char *goextlinkenabled;
|
extern char *goextlinkenabled;
|
||||||
extern char *goversion;
|
extern char *goversion;
|
||||||
extern char *defaultcc;
|
extern char *defaultcc;
|
||||||
extern char *defaultcxx;
|
extern char *defaultcxxtarget;
|
||||||
|
extern char *defaultcctarget;
|
||||||
extern char *workdir;
|
extern char *workdir;
|
||||||
extern char *tooldir;
|
extern char *tooldir;
|
||||||
extern char *slash;
|
extern char *slash;
|
||||||
|
15
src/cmd/dist/build.c
vendored
15
src/cmd/dist/build.c
vendored
@ -27,7 +27,8 @@ char *gochar;
|
|||||||
char *goversion;
|
char *goversion;
|
||||||
char *slash; // / for unix, \ for windows
|
char *slash; // / for unix, \ for windows
|
||||||
char *defaultcc;
|
char *defaultcc;
|
||||||
char *defaultcxx;
|
char *defaultcxxtarget;
|
||||||
|
char *defaultcctarget;
|
||||||
bool rebuildall;
|
bool rebuildall;
|
||||||
bool defaultclang;
|
bool defaultclang;
|
||||||
|
|
||||||
@ -166,6 +167,14 @@ init(void)
|
|||||||
}
|
}
|
||||||
defaultcc = btake(&b);
|
defaultcc = btake(&b);
|
||||||
|
|
||||||
|
xgetenv(&b, "CC_FOR_TARGET");
|
||||||
|
if(b.len == 0) {
|
||||||
|
bprintf(&b, defaultcc);
|
||||||
|
}
|
||||||
|
defaultcctarget = btake(&b);
|
||||||
|
|
||||||
|
xgetenv(&b, "CXX_FOR_TARGET");
|
||||||
|
if(b.len == 0) {
|
||||||
xgetenv(&b, "CXX");
|
xgetenv(&b, "CXX");
|
||||||
if(b.len == 0) {
|
if(b.len == 0) {
|
||||||
if(defaultclang)
|
if(defaultclang)
|
||||||
@ -173,7 +182,8 @@ init(void)
|
|||||||
else
|
else
|
||||||
bprintf(&b, "g++");
|
bprintf(&b, "g++");
|
||||||
}
|
}
|
||||||
defaultcxx = btake(&b);
|
}
|
||||||
|
defaultcxxtarget = btake(&b);
|
||||||
|
|
||||||
xsetenv("GOROOT", goroot);
|
xsetenv("GOROOT", goroot);
|
||||||
xsetenv("GOARCH", goarch);
|
xsetenv("GOARCH", goarch);
|
||||||
@ -1537,6 +1547,7 @@ cmdenv(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
xprintf(format, "CC", defaultcc);
|
xprintf(format, "CC", defaultcc);
|
||||||
|
xprintf(format, "CC_FOR_TARGET", defaultcctarget);
|
||||||
xprintf(format, "GOROOT", goroot);
|
xprintf(format, "GOROOT", goroot);
|
||||||
xprintf(format, "GOBIN", gobin);
|
xprintf(format, "GOBIN", gobin);
|
||||||
xprintf(format, "GOARCH", goarch);
|
xprintf(format, "GOARCH", goarch);
|
||||||
|
2
src/cmd/dist/buildgo.c
vendored
2
src/cmd/dist/buildgo.c
vendored
@ -31,7 +31,7 @@ mkzdefaultcc(char *dir, char *file)
|
|||||||
"\n"
|
"\n"
|
||||||
"const defaultCC = `%s`\n"
|
"const defaultCC = `%s`\n"
|
||||||
"const defaultCXX = `%s`\n",
|
"const defaultCXX = `%s`\n",
|
||||||
defaultcc, defaultcxx);
|
defaultcctarget, defaultcxxtarget);
|
||||||
|
|
||||||
writefile(&out, file, 0);
|
writefile(&out, file, 0);
|
||||||
|
|
||||||
|
@ -1708,11 +1708,10 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
|
|||||||
if buildContext.InstallSuffix != "" {
|
if buildContext.InstallSuffix != "" {
|
||||||
ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
|
ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
|
||||||
}
|
}
|
||||||
if cxx {
|
// If the user has not specified the -extld option, then specify the
|
||||||
// The program includes C++ code. If the user has not
|
// appropriate linker. In case of C++ code, use the compiler named
|
||||||
// specified the -extld option, then default to
|
// by the CXX environment variable or defaultCXX if CXX is not set.
|
||||||
// linking with the compiler named by the CXX
|
// Else, use the CC environment variable and defaultCC as fallback.
|
||||||
// environment variable, or g++ if CXX is not set.
|
|
||||||
extld := false
|
extld := false
|
||||||
for _, f := range ldflags {
|
for _, f := range ldflags {
|
||||||
if f == "-extld" || strings.HasPrefix(f, "-extld=") {
|
if f == "-extld" || strings.HasPrefix(f, "-extld=") {
|
||||||
@ -1721,9 +1720,11 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !extld {
|
if !extld {
|
||||||
compiler := strings.Fields(os.Getenv("CXX"))
|
var compiler []string
|
||||||
if len(compiler) == 0 {
|
if cxx {
|
||||||
compiler = []string{"g++"}
|
compiler = ccompilerPath("CXX", defaultCXX)
|
||||||
|
} else {
|
||||||
|
compiler = ccompilerPath("CC", defaultCC)
|
||||||
}
|
}
|
||||||
ldflags = append(ldflags, "-extld="+compiler[0])
|
ldflags = append(ldflags, "-extld="+compiler[0])
|
||||||
if len(compiler) > 1 {
|
if len(compiler) > 1 {
|
||||||
@ -1745,7 +1746,6 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
|
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1973,15 +1973,12 @@ func (b *builder) gxxCmd(objdir string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ccompilerCmd returns a command line prefix for the given environment
|
// ccompilerCmd returns a command line prefix for the given environment
|
||||||
// variable and using the default command when the variable is empty
|
// variable and using the default command when the variable is empty.
|
||||||
func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
||||||
// NOTE: env.go's mkEnv knows that the first three
|
// NOTE: env.go's mkEnv knows that the first three
|
||||||
// strings returned are "gcc", "-I", objdir (and cuts them off).
|
// strings returned are "gcc", "-I", objdir (and cuts them off).
|
||||||
|
|
||||||
compiler := strings.Fields(os.Getenv(envvar))
|
compiler := ccompilerPath(envvar, defcmd)
|
||||||
if len(compiler) == 0 {
|
|
||||||
compiler = strings.Fields(defcmd)
|
|
||||||
}
|
|
||||||
a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
|
a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
|
||||||
a = append(a, compiler[1:]...)
|
a = append(a, compiler[1:]...)
|
||||||
|
|
||||||
@ -2039,6 +2036,16 @@ func envList(key string) []string {
|
|||||||
return strings.Fields(os.Getenv(key))
|
return strings.Fields(os.Getenv(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ccompilerCmd returns the compilerpath for the given environment
|
||||||
|
// variable and using the default command when the variable is empty.
|
||||||
|
func ccompilerPath(envvar, defcmd string) []string {
|
||||||
|
compiler := envList(envvar)
|
||||||
|
if len(compiler) == 0 {
|
||||||
|
compiler = strings.Fields(defcmd)
|
||||||
|
}
|
||||||
|
return compiler
|
||||||
|
}
|
||||||
|
|
||||||
var cgoRe = regexp.MustCompile(`[/\\:]`)
|
var cgoRe = regexp.MustCompile(`[/\\:]`)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -35,10 +35,15 @@
|
|||||||
# controls the default behavior of the linker's -linkmode option. The
|
# controls the default behavior of the linker's -linkmode option. The
|
||||||
# default value depends on the system.
|
# default value depends on the system.
|
||||||
#
|
#
|
||||||
# CC: Command line to run to get at host C compiler.
|
# CC: Command line to run to compile C code for GOHOSTARCH.
|
||||||
# Default is "gcc". Also supported: "clang".
|
# Default is "gcc". Also supported: "clang".
|
||||||
# CXX: Command line to run to get at host C++ compiler, only recorded
|
#
|
||||||
# for cgo use. Default is "g++". Also supported: "clang++".
|
# CC_FOR_TARGET: Command line to run to compile C code for GOARCH.
|
||||||
|
# This is used by cgo. Default is CC.
|
||||||
|
#
|
||||||
|
# CXX_FOR_TARGET: Command line to run to compile C++ code for GOARCH.
|
||||||
|
# This is used by cgo. Default is CXX, or, if that is not set,
|
||||||
|
# "g++" or "clang++".
|
||||||
#
|
#
|
||||||
# GO_DISTFLAGS: extra flags to provide to "dist bootstrap". Use "-s"
|
# GO_DISTFLAGS: extra flags to provide to "dist bootstrap". Use "-s"
|
||||||
# to build a statically linked toolchain.
|
# to build a statically linked toolchain.
|
||||||
@ -153,13 +158,15 @@ echo
|
|||||||
|
|
||||||
if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
|
if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
|
||||||
echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
|
echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
|
||||||
GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
|
# CC_FOR_TARGET is recorded as the default compiler for the go tool. When building for the host, however,
|
||||||
|
# use the host compiler, CC, from `cmd/dist/dist env` instead.
|
||||||
|
CC=$CC GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
|
||||||
"$GOTOOLDIR"/go_bootstrap install -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
|
"$GOTOOLDIR"/go_bootstrap install -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "# Building packages and commands for $GOOS/$GOARCH."
|
echo "# Building packages and commands for $GOOS/$GOARCH."
|
||||||
"$GOTOOLDIR"/go_bootstrap install $GO_FLAGS -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
|
CC=$CC_FOR_TARGET "$GOTOOLDIR"/go_bootstrap install $GO_FLAGS -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
|
||||||
echo
|
echo
|
||||||
|
|
||||||
rm -f "$GOTOOLDIR"/go_bootstrap
|
rm -f "$GOTOOLDIR"/go_bootstrap
|
||||||
|
@ -303,8 +303,7 @@ func defaultContext() Context {
|
|||||||
case "0":
|
case "0":
|
||||||
c.CgoEnabled = false
|
c.CgoEnabled = false
|
||||||
default:
|
default:
|
||||||
// golang.org/issue/5141
|
// cgo must be explicitly enabled for cross compilation builds
|
||||||
// cgo should be disabled for cross compilation builds
|
|
||||||
if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
|
if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
|
||||||
c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
|
c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user