]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go, cmd/cgo, make.bash: cross compiling with cgo enabled
authorElias Naur <elias.naur@gmail.com>
Thu, 6 Feb 2014 17:11:00 +0000 (09:11 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 6 Feb 2014 17:11:00 +0000 (09:11 -0800)
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

src/cmd/dist/a.h
src/cmd/dist/build.c
src/cmd/dist/buildgo.c
src/cmd/go/build.go
src/make.bash
src/pkg/go/build/build.go

index 3052e515b3164faa3472625e4b89c0bbeb0284ef..6222e5060414f9ea75a1cf6ffce86b78c13cbb92 100644 (file)
@@ -75,7 +75,8 @@ extern char *goroot_final;
 extern char *goextlinkenabled;
 extern char *goversion;
 extern char *defaultcc;
-extern char *defaultcxx;
+extern char *defaultcxxtarget;
+extern char *defaultcctarget;
 extern char *workdir;
 extern char *tooldir;
 extern char *slash;
index 29656f3374e96622bd8644793b398c65b2e45114..05462492269bd5b36932435b215978c25f94376e 100644 (file)
@@ -27,7 +27,8 @@ char *gochar;
 char *goversion;
 char *slash;   // / for unix, \ for windows
 char *defaultcc;
-char *defaultcxx;
+char *defaultcxxtarget;
+char *defaultcctarget;
 bool   rebuildall;
 bool defaultclang;
 
@@ -166,14 +167,23 @@ init(void)
        }
        defaultcc = btake(&b);
 
-       xgetenv(&b, "CXX");
+       xgetenv(&b, "CC_FOR_TARGET");
        if(b.len == 0) {
-               if(defaultclang)
-                       bprintf(&b, "clang++");
-               else
-                       bprintf(&b, "g++");
+               bprintf(&b, defaultcc);
+       }
+       defaultcctarget = btake(&b);
+
+       xgetenv(&b, "CXX_FOR_TARGET");
+       if(b.len == 0) {
+               xgetenv(&b, "CXX");
+               if(b.len == 0) {
+                       if(defaultclang)
+                               bprintf(&b, "clang++");
+                       else
+                               bprintf(&b, "g++");
+               }
        }
-       defaultcxx = btake(&b);
+       defaultcxxtarget = btake(&b);
 
        xsetenv("GOROOT", goroot);
        xsetenv("GOARCH", goarch);
@@ -1537,6 +1547,7 @@ cmdenv(int argc, char **argv)
                usage();
 
        xprintf(format, "CC", defaultcc);
+       xprintf(format, "CC_FOR_TARGET", defaultcctarget);
        xprintf(format, "GOROOT", goroot);
        xprintf(format, "GOBIN", gobin);
        xprintf(format, "GOARCH", goarch);
index a340252bc53e013d9d9944546a331490d53c673a..41208fac5f734d3e3078d868a77a5c88d11fbdcc 100644 (file)
@@ -31,7 +31,7 @@ mkzdefaultcc(char *dir, char *file)
                "\n"
                "const defaultCC = `%s`\n"
                "const defaultCXX = `%s`\n",
-               defaultcc, defaultcxx);
+               defaultcctarget, defaultcxxtarget);
 
        writefile(&out, file, 0);
 
index da90f0c0294d703e2bdf8e4b5dd4fe6877b59a1e..4942a1b65f2d97ac957827193ffc76608bff2704 100644 (file)
@@ -1708,42 +1708,42 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
        if buildContext.InstallSuffix != "" {
                ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
        }
-       if cxx {
-               // The program includes C++ code.  If the user has not
-               // specified the -extld option, then default to
-               // linking with the compiler named by the CXX
-               // environment variable, or g++ if CXX is not set.
-               extld := false
-               for _, f := range ldflags {
-                       if f == "-extld" || strings.HasPrefix(f, "-extld=") {
-                               extld = true
-                               break
-                       }
+       // If the user has not specified the -extld option, then specify the
+       // appropriate linker. In case of C++ code, use the compiler named
+       // by the CXX environment variable or defaultCXX if CXX is not set.
+       // Else, use the CC environment variable and defaultCC as fallback.
+       extld := false
+       for _, f := range ldflags {
+               if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+                       extld = true
+                       break
                }
-               if !extld {
-                       compiler := strings.Fields(os.Getenv("CXX"))
-                       if len(compiler) == 0 {
-                               compiler = []string{"g++"}
-                       }
-                       ldflags = append(ldflags, "-extld="+compiler[0])
-                       if len(compiler) > 1 {
-                               extldflags := false
-                               add := strings.Join(compiler[1:], " ")
-                               for i, f := range ldflags {
-                                       if f == "-extldflags" && i+1 < len(ldflags) {
-                                               ldflags[i+1] = add + " " + ldflags[i+1]
-                                               extldflags = true
-                                               break
-                                       } else if strings.HasPrefix(f, "-extldflags=") {
-                                               ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
-                                               extldflags = true
-                                               break
-                                       }
-                               }
-                               if !extldflags {
-                                       ldflags = append(ldflags, "-extldflags="+add)
+       }
+       if !extld {
+               var compiler []string
+               if cxx {
+                       compiler = ccompilerPath("CXX", defaultCXX)
+               } else {
+                       compiler = ccompilerPath("CC", defaultCC)
+               }
+               ldflags = append(ldflags, "-extld="+compiler[0])
+               if len(compiler) > 1 {
+                       extldflags := false
+                       add := strings.Join(compiler[1:], " ")
+                       for i, f := range ldflags {
+                               if f == "-extldflags" && i+1 < len(ldflags) {
+                                       ldflags[i+1] = add + " " + ldflags[i+1]
+                                       extldflags = true
+                                       break
+                               } else if strings.HasPrefix(f, "-extldflags=") {
+                                       ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+                                       extldflags = true
+                                       break
                                }
                        }
+                       if !extldflags {
+                               ldflags = append(ldflags, "-extldflags="+add)
+                       }
                }
        }
        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
-// 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 {
        // NOTE: env.go's mkEnv knows that the first three
        // strings returned are "gcc", "-I", objdir (and cuts them off).
 
-       compiler := strings.Fields(os.Getenv(envvar))
-       if len(compiler) == 0 {
-               compiler = strings.Fields(defcmd)
-       }
+       compiler := ccompilerPath(envvar, defcmd)
        a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
        a = append(a, compiler[1:]...)
 
@@ -2039,6 +2036,16 @@ func envList(key string) []string {
        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 (
index 877d1e5ebb659ae76ee0e2295b8313641c3395a5..bfcb5d58eab07f49e7b4affa10edee67083d2b9e 100755 (executable)
 # controls the default behavior of the linker's -linkmode option.  The
 # 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".
-# 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"
 # to build a statically linked toolchain.
@@ -153,13 +158,15 @@ echo
 
 if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
        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
        echo
 fi
 
 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
 
 rm -f "$GOTOOLDIR"/go_bootstrap
index 50d2fb4aeba4bc6536ab7004d5a1f6a36df75e88..e4fc853b4a3c6b6a6a8ba70350ab234590167956 100644 (file)
@@ -303,8 +303,7 @@ func defaultContext() Context {
        case "0":
                c.CgoEnabled = false
        default:
-               // golang.org/issue/5141
-               // cgo should be disabled for cross compilation builds
+               // cgo must be explicitly enabled for cross compilation builds
                if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
                        c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
                        break