mirror of
https://github.com/golang/go
synced 2024-11-20 08:04:42 -07:00
cmd/go: check compiler flags per compilers in gccSupportsFlag
Current code always uses a C compilers for checking compiler flags even for non-C compilers. This CL solves the issue. Fixes #21736 Change-Id: I5eaddd5fe7d5df699eb2384518b21e6064ca31cf Reviewed-on: https://go-review.googlesource.com/61270 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
43807e0f47
commit
d254c61309
@ -652,7 +652,7 @@ type Builder struct {
|
|||||||
WorkDir string // the temporary work directory (ends in filepath.Separator)
|
WorkDir string // the temporary work directory (ends in filepath.Separator)
|
||||||
actionCache map[cacheKey]*Action // a cache of already-constructed actions
|
actionCache map[cacheKey]*Action // a cache of already-constructed actions
|
||||||
mkdirCache map[string]bool // a cache of created directories
|
mkdirCache map[string]bool // a cache of created directories
|
||||||
flagCache map[string]bool // a cache of supported compiler flags
|
flagCache map[[2]string]bool // a cache of supported compiler flags
|
||||||
Print func(args ...interface{}) (int, error)
|
Print func(args ...interface{}) (int, error)
|
||||||
|
|
||||||
output sync.Mutex
|
output sync.Mutex
|
||||||
@ -2958,7 +2958,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out string, allaction
|
|||||||
// libffi.
|
// libffi.
|
||||||
ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
|
ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
|
||||||
|
|
||||||
if nopie := b.gccNoPie(); nopie != "" {
|
if nopie := b.gccNoPie([]string{tools.linker()}); nopie != "" {
|
||||||
ldflags = append(ldflags, nopie)
|
ldflags = append(ldflags, nopie)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3134,23 +3134,23 @@ func (b *Builder) gccld(p *load.Package, out string, flags []string, objs []stri
|
|||||||
// gccCmd returns a gcc command line prefix
|
// gccCmd returns a gcc command line prefix
|
||||||
// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
|
// 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", cfg.DefaultCC, objdir)
|
return b.compilerCmd("CC", cfg.DefaultCC, objdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gxxCmd returns a g++ command line prefix
|
// gxxCmd returns a g++ command line prefix
|
||||||
// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
|
// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
|
||||||
func (b *Builder) GxxCmd(objdir string) []string {
|
func (b *Builder) GxxCmd(objdir string) []string {
|
||||||
return b.ccompilerCmd("CXX", cfg.DefaultCXX, objdir)
|
return b.compilerCmd("CXX", cfg.DefaultCXX, objdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gfortranCmd returns a gfortran command line prefix.
|
// gfortranCmd returns a gfortran command line prefix.
|
||||||
func (b *Builder) gfortranCmd(objdir string) []string {
|
func (b *Builder) gfortranCmd(objdir string) []string {
|
||||||
return b.ccompilerCmd("FC", "gfortran", objdir)
|
return b.compilerCmd("FC", "gfortran", objdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ccompilerCmd returns a command line prefix for the given environment
|
// compilerCmd 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) compilerCmd(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).
|
||||||
|
|
||||||
@ -3176,11 +3176,11 @@ func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// disable ASCII art in clang errors, if possible
|
// disable ASCII art in clang errors, if possible
|
||||||
if b.gccSupportsFlag("-fno-caret-diagnostics") {
|
if b.gccSupportsFlag(compiler, "-fno-caret-diagnostics") {
|
||||||
a = append(a, "-fno-caret-diagnostics")
|
a = append(a, "-fno-caret-diagnostics")
|
||||||
}
|
}
|
||||||
// clang is too smart about command-line arguments
|
// clang is too smart about command-line arguments
|
||||||
if b.gccSupportsFlag("-Qunused-arguments") {
|
if b.gccSupportsFlag(compiler, "-Qunused-arguments") {
|
||||||
a = append(a, "-Qunused-arguments")
|
a = append(a, "-Qunused-arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3188,13 +3188,13 @@ func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
|||||||
a = append(a, "-fmessage-length=0")
|
a = append(a, "-fmessage-length=0")
|
||||||
|
|
||||||
// Tell gcc not to include the work directory in object files.
|
// Tell gcc not to include the work directory in object files.
|
||||||
if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
|
if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
|
||||||
a = append(a, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
|
a = append(a, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell gcc not to include flags in object files, which defeats the
|
// Tell gcc not to include flags in object files, which defeats the
|
||||||
// point of -fdebug-prefix-map above.
|
// point of -fdebug-prefix-map above.
|
||||||
if b.gccSupportsFlag("-gno-record-gcc-switches") {
|
if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") {
|
||||||
a = append(a, "-gno-record-gcc-switches")
|
a = append(a, "-gno-record-gcc-switches")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3212,21 +3212,23 @@ func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
|||||||
// with PIE (position independent executables) enabled by default,
|
// with PIE (position independent executables) enabled by default,
|
||||||
// -no-pie must be passed when doing a partial link with -Wl,-r.
|
// -no-pie must be passed when doing a partial link with -Wl,-r.
|
||||||
// But -no-pie is not supported by all compilers, and clang spells it -nopie.
|
// But -no-pie is not supported by all compilers, and clang spells it -nopie.
|
||||||
func (b *Builder) gccNoPie() string {
|
func (b *Builder) gccNoPie(linker []string) string {
|
||||||
if b.gccSupportsFlag("-no-pie") {
|
if b.gccSupportsFlag(linker, "-no-pie") {
|
||||||
return "-no-pie"
|
return "-no-pie"
|
||||||
}
|
}
|
||||||
if b.gccSupportsFlag("-nopie") {
|
if b.gccSupportsFlag(linker, "-nopie") {
|
||||||
return "-nopie"
|
return "-nopie"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// gccSupportsFlag checks to see if the compiler supports a flag.
|
// gccSupportsFlag checks to see if the compiler supports a flag.
|
||||||
func (b *Builder) gccSupportsFlag(flag string) bool {
|
func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
|
||||||
|
key := [2]string{compiler[0], flag}
|
||||||
|
|
||||||
b.exec.Lock()
|
b.exec.Lock()
|
||||||
defer b.exec.Unlock()
|
defer b.exec.Unlock()
|
||||||
if b, ok := b.flagCache[flag]; ok {
|
if b, ok := b.flagCache[key]; ok {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
if b.flagCache == nil {
|
if b.flagCache == nil {
|
||||||
@ -3239,9 +3241,9 @@ func (b *Builder) gccSupportsFlag(flag string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.flagCache = make(map[string]bool)
|
b.flagCache = make(map[[2]string]bool)
|
||||||
}
|
}
|
||||||
cmdArgs := append(envList("CC", cfg.DefaultCC), flag, "-c", "trivial.c")
|
cmdArgs := append(compiler, flag, "-c", "trivial.c")
|
||||||
if cfg.BuildN || cfg.BuildX {
|
if cfg.BuildN || cfg.BuildX {
|
||||||
b.Showcmd(b.WorkDir, "%s", joinUnambiguously(cmdArgs))
|
b.Showcmd(b.WorkDir, "%s", joinUnambiguously(cmdArgs))
|
||||||
if cfg.BuildN {
|
if cfg.BuildN {
|
||||||
@ -3253,7 +3255,7 @@ func (b *Builder) gccSupportsFlag(flag string) bool {
|
|||||||
cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
|
cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
|
supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
|
||||||
b.flagCache[flag] = supported
|
b.flagCache[key] = supported
|
||||||
return supported
|
return supported
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3555,7 +3557,13 @@ func (b *Builder) collect(p *load.Package, objdir, ofile string, cgoLDFLAGS, out
|
|||||||
|
|
||||||
ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
|
ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
|
||||||
|
|
||||||
if flag := b.gccNoPie(); flag != "" {
|
var linker []string
|
||||||
|
if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
|
||||||
|
linker = envList("CXX", cfg.DefaultCXX)
|
||||||
|
} else {
|
||||||
|
linker = envList("CC", cfg.DefaultCC)
|
||||||
|
}
|
||||||
|
if flag := b.gccNoPie(linker); flag != "" {
|
||||||
ldflags = append(ldflags, flag)
|
ldflags = append(ldflags, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user