mirror of
https://github.com/golang/go
synced 2024-11-18 04:24:47 -07:00
build: on OS X 10.8 and later, use clang instead of gcc
Fixes #5822. Will no doubt cause other problems, but Apple has forced our hand. R=golang-dev, bradfitz, khr CC=golang-dev https://golang.org/cl/12350044
This commit is contained in:
parent
337407d847
commit
2ddb672ddc
@ -646,19 +646,20 @@ func (p *Package) rewriteRef(f *File) {
|
||||
}
|
||||
}
|
||||
|
||||
// gccName returns the name of the compiler to run. Use $CC if set in
|
||||
// the environment, otherwise just "gcc".
|
||||
|
||||
func (p *Package) gccName() string {
|
||||
// gccBaseCmd returns the start of the compiler command line.
|
||||
// It uses $CC if set, or else $GCC, or else the compiler recorded
|
||||
// during the initial build as defaultCC.
|
||||
// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
|
||||
func (p *Package) gccBaseCmd() []string {
|
||||
// Use $CC if set, since that's what the build uses.
|
||||
if ret := os.Getenv("CC"); ret != "" {
|
||||
if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
|
||||
return ret
|
||||
}
|
||||
// Fall back to $GCC if set, since that's what we used to use.
|
||||
if ret := os.Getenv("GCC"); ret != "" {
|
||||
// Try $GCC if set, since that's what we used to use.
|
||||
if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
|
||||
return ret
|
||||
}
|
||||
return "gcc"
|
||||
return strings.Fields(defaultCC)
|
||||
}
|
||||
|
||||
// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
|
||||
@ -681,17 +682,16 @@ func gccTmp() string {
|
||||
// gccCmd returns the gcc command line to use for compiling
|
||||
// the input.
|
||||
func (p *Package) gccCmd() []string {
|
||||
c := []string{
|
||||
p.gccName(),
|
||||
c := append(p.gccBaseCmd(),
|
||||
"-Wall", // many warnings
|
||||
"-Werror", // warnings are errors
|
||||
"-o" + gccTmp(), // write object to tmp
|
||||
"-o"+gccTmp(), // write object to tmp
|
||||
"-gdwarf-2", // generate DWARF v2 debugging symbols
|
||||
"-fno-eliminate-unused-debug-types", // gets rid of e.g. untyped enum otherwise
|
||||
"-c", // do not link
|
||||
"-xc", // input language is C
|
||||
}
|
||||
if strings.Contains(p.gccName(), "clang") {
|
||||
)
|
||||
if strings.Contains(c[0], "clang") {
|
||||
c = append(c,
|
||||
"-ferror-limit=0",
|
||||
// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
|
||||
@ -800,7 +800,7 @@ func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte)
|
||||
// #defines that gcc encountered while processing the input
|
||||
// and its included files.
|
||||
func (p *Package) gccDefines(stdin []byte) string {
|
||||
base := []string{p.gccName(), "-E", "-dM", "-xc"}
|
||||
base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
|
||||
base = append(base, p.gccMachine()...)
|
||||
stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
|
||||
return stdout
|
||||
|
@ -498,7 +498,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
||||
// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
|
||||
// and http://golang.org/issue/5603.
|
||||
extraAttr := ""
|
||||
if !strings.Contains(p.gccName(), "clang") && (goarch == "amd64" || goarch == "386") {
|
||||
if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
|
||||
extraAttr = ", __gcc_struct__"
|
||||
}
|
||||
fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__%v)) *a = v;\n", ctype, extraAttr)
|
||||
|
5
src/cmd/dist/a.h
vendored
5
src/cmd/dist/a.h
vendored
@ -74,10 +74,12 @@ extern char *goroot;
|
||||
extern char *goroot_final;
|
||||
extern char *goextlinkenabled;
|
||||
extern char *goversion;
|
||||
extern char *defaultcc;
|
||||
extern char *workdir;
|
||||
extern char *tooldir;
|
||||
extern char *slash;
|
||||
extern bool rebuildall;
|
||||
extern bool defaultclang;
|
||||
|
||||
int find(char*, char**, int);
|
||||
void init(void);
|
||||
@ -100,6 +102,9 @@ void mkzgoos(char*, char*);
|
||||
void mkzruntimedefs(char*, char*);
|
||||
void mkzversion(char*, char*);
|
||||
|
||||
// buildgo.c
|
||||
void mkzdefaultcc(char*, char*);
|
||||
|
||||
// goc2c.c
|
||||
void goc2c(char*, char*);
|
||||
|
||||
|
29
src/cmd/dist/build.c
vendored
29
src/cmd/dist/build.c
vendored
@ -26,8 +26,9 @@ char *tooldir;
|
||||
char *gochar;
|
||||
char *goversion;
|
||||
char *slash; // / for unix, \ for windows
|
||||
|
||||
bool rebuildall = 0;
|
||||
char *defaultcc;
|
||||
bool rebuildall;
|
||||
bool defaultclang;
|
||||
|
||||
static bool shouldbuild(char*, char*);
|
||||
static void copy(char*, char*, int);
|
||||
@ -146,6 +147,20 @@ init(void)
|
||||
if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
|
||||
fatal("unknown $GO_EXTLINK_ENABLED %s", goextlinkenabled);
|
||||
}
|
||||
|
||||
xgetenv(&b, "CC");
|
||||
if(b.len == 0) {
|
||||
// Use clang on OS X, because gcc is deprecated there.
|
||||
// Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
|
||||
// actually runs clang. We prepare different command
|
||||
// lines for the two binaries, so it matters what we call it.
|
||||
// See golang.org/issue/5822.
|
||||
if(defaultclang)
|
||||
bprintf(&b, "clang");
|
||||
else
|
||||
bprintf(&b, "gcc");
|
||||
}
|
||||
defaultcc = btake(&b);
|
||||
|
||||
xsetenv("GOROOT", goroot);
|
||||
xsetenv("GOARCH", goarch);
|
||||
@ -525,6 +540,9 @@ static struct {
|
||||
"../ld/*",
|
||||
"enam.c",
|
||||
}},
|
||||
{"cmd/go", {
|
||||
"zdefaultcc.go",
|
||||
}},
|
||||
{"cmd/", {
|
||||
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libmach.a",
|
||||
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libbio.a",
|
||||
@ -557,6 +575,7 @@ static struct {
|
||||
{"opnames.h", gcopnames},
|
||||
{"enam.c", mkenam},
|
||||
{"zasm_", mkzasm},
|
||||
{"zdefaultcc.go", mkzdefaultcc},
|
||||
{"zsys_", mkzsys},
|
||||
{"zgoarch_", mkzgoarch},
|
||||
{"zgoos_", mkzgoos},
|
||||
@ -616,10 +635,7 @@ install(char *dir)
|
||||
|
||||
// set up gcc command line on first run.
|
||||
if(gccargs.len == 0) {
|
||||
xgetenv(&b, "CC");
|
||||
if(b.len == 0)
|
||||
bprintf(&b, "gcc");
|
||||
clang = contains(bstr(&b), "clang");
|
||||
bprintf(&b, "%s", defaultcc);
|
||||
splitfields(&gccargs, bstr(&b));
|
||||
for(i=0; i<nelem(proto_gccargs); i++)
|
||||
vadd(&gccargs, proto_gccargs[i]);
|
||||
@ -1443,6 +1459,7 @@ cmdenv(int argc, char **argv)
|
||||
if(argc > 0)
|
||||
usage();
|
||||
|
||||
xprintf(format, "CC", defaultcc);
|
||||
xprintf(format, "GOROOT", goroot);
|
||||
xprintf(format, "GOBIN", gobin);
|
||||
xprintf(format, "GOARCH", goarch);
|
||||
|
21
src/cmd/dist/unix.c
vendored
21
src/cmd/dist/unix.c
vendored
@ -651,6 +651,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Buf b;
|
||||
int osx;
|
||||
struct utsname u;
|
||||
|
||||
setvbuf(stdout, nil, _IOLBF, 0);
|
||||
@ -700,17 +701,23 @@ main(int argc, char **argv)
|
||||
if(strcmp(gohostarch, "arm") == 0)
|
||||
maxnbg = 1;
|
||||
|
||||
// The OS X 10.6 linker does not support external
|
||||
// linking mode; see
|
||||
// https://code.google.com/p/go/issues/detail?id=5130 .
|
||||
// The mapping from the uname release field to the OS X
|
||||
// version number is complicated, but basically 10 or under is
|
||||
// OS X 10.6 or earlier.
|
||||
// The OS X 10.6 linker does not support external linking mode.
|
||||
// See golang.org/issue/5130.
|
||||
//
|
||||
// OS X 10.6 does not work with clang either, but OS X 10.9 requires it.
|
||||
// It seems to work with OS X 10.8, so we default to clang for 10.8 and later.
|
||||
// See golang.org/issue/5822.
|
||||
//
|
||||
// Roughly, OS X 10.N shows up as uname release (N+4),
|
||||
// so OS X 10.6 is uname version 10 and OS X 10.8 is uname version 12.
|
||||
if(strcmp(gohostos, "darwin") == 0) {
|
||||
if(uname(&u) < 0)
|
||||
fatal("uname: %s", strerror(errno));
|
||||
if(u.release[1] == '.' || hasprefix(u.release, "10"))
|
||||
osx = atoi(u.release) - 4;
|
||||
if(osx <= 6)
|
||||
goextlinkenabled = "0";
|
||||
if(osx >= 8)
|
||||
defaultclang = 1;
|
||||
}
|
||||
|
||||
init();
|
||||
|
@ -1772,8 +1772,9 @@ func (b *builder) gccld(p *Package, out string, flags []string, obj []string) er
|
||||
}
|
||||
|
||||
// gccCmd returns a gcc command line prefix
|
||||
// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
|
||||
func (b *builder) gccCmd(objdir string) []string {
|
||||
return b.ccompilerCmd("CC", "gcc", objdir)
|
||||
return b.ccompilerCmd("CC", defaultCC, objdir)
|
||||
}
|
||||
|
||||
// gxxCmd returns a g++ command line prefix
|
||||
@ -1789,7 +1790,7 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
||||
|
||||
compiler := strings.Fields(os.Getenv(envvar))
|
||||
if len(compiler) == 0 {
|
||||
compiler = append(compiler, defcmd)
|
||||
compiler = strings.Fields(defcmd)
|
||||
}
|
||||
a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
|
||||
a = append(a, compiler[1:]...)
|
||||
|
@ -124,7 +124,10 @@ freebsd-386 | freebsd-amd64 | linux-386 | linux-amd64 | netbsd-386 | netbsd-amd6
|
||||
esac
|
||||
) || exit $?
|
||||
|
||||
[ "$CGO_ENABLED" != 1 ] ||
|
||||
# This tests cgo -godefs. That mode is not supported,
|
||||
# so it's okay if it doesn't work on some systems.
|
||||
# In particular, it works badly with clang on OS X.
|
||||
[ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
|
||||
(xcd ../misc/cgo/testcdefs
|
||||
./test.bash || exit 1
|
||||
) || exit $?
|
||||
|
Loading…
Reference in New Issue
Block a user