mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00: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
7 changed files with 64 additions and 31 deletions
|
|
@ -646,19 +646,20 @@ func (p *Package) rewriteRef(f *File) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// gccName returns the name of the compiler to run. Use $CC if set in
|
// gccBaseCmd returns the start of the compiler command line.
|
||||||
// the environment, otherwise just "gcc".
|
// It uses $CC if set, or else $GCC, or else the compiler recorded
|
||||||
|
// during the initial build as defaultCC.
|
||||||
func (p *Package) gccName() string {
|
// 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.
|
// 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
|
return ret
|
||||||
}
|
}
|
||||||
// Fall back to $GCC if set, since that's what we used to use.
|
// Try $GCC if set, since that's what we used to use.
|
||||||
if ret := os.Getenv("GCC"); ret != "" {
|
if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
return "gcc"
|
return strings.Fields(defaultCC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
|
// 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
|
// gccCmd returns the gcc command line to use for compiling
|
||||||
// the input.
|
// the input.
|
||||||
func (p *Package) gccCmd() []string {
|
func (p *Package) gccCmd() []string {
|
||||||
c := []string{
|
c := append(p.gccBaseCmd(),
|
||||||
p.gccName(),
|
|
||||||
"-Wall", // many warnings
|
"-Wall", // many warnings
|
||||||
"-Werror", // warnings are errors
|
"-Werror", // warnings are errors
|
||||||
"-o" + gccTmp(), // write object to tmp
|
"-o"+gccTmp(), // write object to tmp
|
||||||
"-gdwarf-2", // generate DWARF v2 debugging symbols
|
"-gdwarf-2", // generate DWARF v2 debugging symbols
|
||||||
"-fno-eliminate-unused-debug-types", // gets rid of e.g. untyped enum otherwise
|
"-fno-eliminate-unused-debug-types", // gets rid of e.g. untyped enum otherwise
|
||||||
"-c", // do not link
|
"-c", // do not link
|
||||||
"-xc", // input language is C
|
"-xc", // input language is C
|
||||||
}
|
)
|
||||||
if strings.Contains(p.gccName(), "clang") {
|
if strings.Contains(c[0], "clang") {
|
||||||
c = append(c,
|
c = append(c,
|
||||||
"-ferror-limit=0",
|
"-ferror-limit=0",
|
||||||
// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
|
// 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
|
// #defines that gcc encountered while processing the input
|
||||||
// and its included files.
|
// and its included files.
|
||||||
func (p *Package) gccDefines(stdin []byte) string {
|
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()...)
|
base = append(base, p.gccMachine()...)
|
||||||
stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
|
stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
|
||||||
return stdout
|
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,
|
// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
|
||||||
// and http://golang.org/issue/5603.
|
// and http://golang.org/issue/5603.
|
||||||
extraAttr := ""
|
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__"
|
extraAttr = ", __gcc_struct__"
|
||||||
}
|
}
|
||||||
fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__%v)) *a = v;\n", ctype, extraAttr)
|
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 *goroot_final;
|
||||||
extern char *goextlinkenabled;
|
extern char *goextlinkenabled;
|
||||||
extern char *goversion;
|
extern char *goversion;
|
||||||
|
extern char *defaultcc;
|
||||||
extern char *workdir;
|
extern char *workdir;
|
||||||
extern char *tooldir;
|
extern char *tooldir;
|
||||||
extern char *slash;
|
extern char *slash;
|
||||||
extern bool rebuildall;
|
extern bool rebuildall;
|
||||||
|
extern bool defaultclang;
|
||||||
|
|
||||||
int find(char*, char**, int);
|
int find(char*, char**, int);
|
||||||
void init(void);
|
void init(void);
|
||||||
|
|
@ -100,6 +102,9 @@ void mkzgoos(char*, char*);
|
||||||
void mkzruntimedefs(char*, char*);
|
void mkzruntimedefs(char*, char*);
|
||||||
void mkzversion(char*, char*);
|
void mkzversion(char*, char*);
|
||||||
|
|
||||||
|
// buildgo.c
|
||||||
|
void mkzdefaultcc(char*, char*);
|
||||||
|
|
||||||
// goc2c.c
|
// goc2c.c
|
||||||
void goc2c(char*, char*);
|
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 *gochar;
|
||||||
char *goversion;
|
char *goversion;
|
||||||
char *slash; // / for unix, \ for windows
|
char *slash; // / for unix, \ for windows
|
||||||
|
char *defaultcc;
|
||||||
bool rebuildall = 0;
|
bool rebuildall;
|
||||||
|
bool defaultclang;
|
||||||
|
|
||||||
static bool shouldbuild(char*, char*);
|
static bool shouldbuild(char*, char*);
|
||||||
static void copy(char*, char*, int);
|
static void copy(char*, char*, int);
|
||||||
|
|
@ -146,6 +147,20 @@ init(void)
|
||||||
if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
|
if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
|
||||||
fatal("unknown $GO_EXTLINK_ENABLED %s", goextlinkenabled);
|
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("GOROOT", goroot);
|
||||||
xsetenv("GOARCH", goarch);
|
xsetenv("GOARCH", goarch);
|
||||||
|
|
@ -525,6 +540,9 @@ static struct {
|
||||||
"../ld/*",
|
"../ld/*",
|
||||||
"enam.c",
|
"enam.c",
|
||||||
}},
|
}},
|
||||||
|
{"cmd/go", {
|
||||||
|
"zdefaultcc.go",
|
||||||
|
}},
|
||||||
{"cmd/", {
|
{"cmd/", {
|
||||||
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libmach.a",
|
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libmach.a",
|
||||||
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libbio.a",
|
"$GOROOT/pkg/obj/$GOOS_$GOARCH/libbio.a",
|
||||||
|
|
@ -557,6 +575,7 @@ static struct {
|
||||||
{"opnames.h", gcopnames},
|
{"opnames.h", gcopnames},
|
||||||
{"enam.c", mkenam},
|
{"enam.c", mkenam},
|
||||||
{"zasm_", mkzasm},
|
{"zasm_", mkzasm},
|
||||||
|
{"zdefaultcc.go", mkzdefaultcc},
|
||||||
{"zsys_", mkzsys},
|
{"zsys_", mkzsys},
|
||||||
{"zgoarch_", mkzgoarch},
|
{"zgoarch_", mkzgoarch},
|
||||||
{"zgoos_", mkzgoos},
|
{"zgoos_", mkzgoos},
|
||||||
|
|
@ -616,10 +635,7 @@ install(char *dir)
|
||||||
|
|
||||||
// set up gcc command line on first run.
|
// set up gcc command line on first run.
|
||||||
if(gccargs.len == 0) {
|
if(gccargs.len == 0) {
|
||||||
xgetenv(&b, "CC");
|
bprintf(&b, "%s", defaultcc);
|
||||||
if(b.len == 0)
|
|
||||||
bprintf(&b, "gcc");
|
|
||||||
clang = contains(bstr(&b), "clang");
|
|
||||||
splitfields(&gccargs, bstr(&b));
|
splitfields(&gccargs, bstr(&b));
|
||||||
for(i=0; i<nelem(proto_gccargs); i++)
|
for(i=0; i<nelem(proto_gccargs); i++)
|
||||||
vadd(&gccargs, proto_gccargs[i]);
|
vadd(&gccargs, proto_gccargs[i]);
|
||||||
|
|
@ -1443,6 +1459,7 @@ cmdenv(int argc, char **argv)
|
||||||
if(argc > 0)
|
if(argc > 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
|
xprintf(format, "CC", defaultcc);
|
||||||
xprintf(format, "GOROOT", goroot);
|
xprintf(format, "GOROOT", goroot);
|
||||||
xprintf(format, "GOBIN", gobin);
|
xprintf(format, "GOBIN", gobin);
|
||||||
xprintf(format, "GOARCH", goarch);
|
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)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Buf b;
|
Buf b;
|
||||||
|
int osx;
|
||||||
struct utsname u;
|
struct utsname u;
|
||||||
|
|
||||||
setvbuf(stdout, nil, _IOLBF, 0);
|
setvbuf(stdout, nil, _IOLBF, 0);
|
||||||
|
|
@ -700,17 +701,23 @@ main(int argc, char **argv)
|
||||||
if(strcmp(gohostarch, "arm") == 0)
|
if(strcmp(gohostarch, "arm") == 0)
|
||||||
maxnbg = 1;
|
maxnbg = 1;
|
||||||
|
|
||||||
// The OS X 10.6 linker does not support external
|
// The OS X 10.6 linker does not support external linking mode.
|
||||||
// linking mode; see
|
// See golang.org/issue/5130.
|
||||||
// https://code.google.com/p/go/issues/detail?id=5130 .
|
//
|
||||||
// The mapping from the uname release field to the OS X
|
// OS X 10.6 does not work with clang either, but OS X 10.9 requires it.
|
||||||
// version number is complicated, but basically 10 or under is
|
// It seems to work with OS X 10.8, so we default to clang for 10.8 and later.
|
||||||
// OS X 10.6 or earlier.
|
// 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(strcmp(gohostos, "darwin") == 0) {
|
||||||
if(uname(&u) < 0)
|
if(uname(&u) < 0)
|
||||||
fatal("uname: %s", strerror(errno));
|
fatal("uname: %s", strerror(errno));
|
||||||
if(u.release[1] == '.' || hasprefix(u.release, "10"))
|
osx = atoi(u.release) - 4;
|
||||||
|
if(osx <= 6)
|
||||||
goextlinkenabled = "0";
|
goextlinkenabled = "0";
|
||||||
|
if(osx >= 8)
|
||||||
|
defaultclang = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
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
|
// gccCmd returns a gcc command line prefix
|
||||||
|
// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
|
||||||
func (b *builder) gccCmd(objdir string) []string {
|
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
|
// 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))
|
compiler := strings.Fields(os.Getenv(envvar))
|
||||||
if len(compiler) == 0 {
|
if len(compiler) == 0 {
|
||||||
compiler = append(compiler, defcmd)
|
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:]...)
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,10 @@ freebsd-386 | freebsd-amd64 | linux-386 | linux-amd64 | netbsd-386 | netbsd-amd6
|
||||||
esac
|
esac
|
||||||
) || exit $?
|
) || 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
|
(xcd ../misc/cgo/testcdefs
|
||||||
./test.bash || exit 1
|
./test.bash || exit 1
|
||||||
) || exit $?
|
) || exit $?
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue