diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go index c62a41901e..2e3e9d3973 100644 --- a/src/cmd/go/internal/envcmd/env.go +++ b/src/cmd/go/internal/envcmd/env.go @@ -73,11 +73,16 @@ func MkEnv() []cfg.EnvVar { env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386}) } - cmd := b.GccCmd(".", "") - env = append(env, cfg.EnvVar{Name: "CC", Value: cmd[0]}) - env = append(env, cfg.EnvVar{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")}) - cmd = b.GxxCmd(".", "") - env = append(env, cfg.EnvVar{Name: "CXX", Value: cmd[0]}) + cc := cfg.DefaultCC + if env := strings.Fields(os.Getenv("CC")); len(env) > 0 { + cc = env[0] + } + cxx := cfg.DefaultCXX + if env := strings.Fields(os.Getenv("CXX")); len(env) > 0 { + cxx = env[0] + } + env = append(env, cfg.EnvVar{Name: "CC", Value: cc}) + env = append(env, cfg.EnvVar{Name: "CXX", Value: cxx}) if cfg.BuildContext.CgoEnabled { env = append(env, cfg.EnvVar{Name: "CGO_ENABLED", Value: "1"}) @@ -102,19 +107,45 @@ func ExtraEnvVars() []cfg.EnvVar { var b work.Builder b.Init() cppflags, cflags, cxxflags, fflags, ldflags := b.CFlags(&load.Package{}) + cmd := b.GccCmd(".", "") return []cfg.EnvVar{ + // Note: Update the switch in runEnv below when adding to this list. {Name: "CGO_CFLAGS", Value: strings.Join(cflags, " ")}, {Name: "CGO_CPPFLAGS", Value: strings.Join(cppflags, " ")}, {Name: "CGO_CXXFLAGS", Value: strings.Join(cxxflags, " ")}, {Name: "CGO_FFLAGS", Value: strings.Join(fflags, " ")}, {Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")}, {Name: "PKG_CONFIG", Value: b.PkgconfigCmd()}, + {Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")}, } } func runEnv(cmd *base.Command, args []string) { env := cfg.CmdEnv - env = append(env, ExtraEnvVars()...) + + // Do we need to call ExtraEnvVars, which is a bit expensive? + // Only if we're listing all environment variables ("go env") + // or the variables being requested are in the extra list. + needExtra := true + if len(args) > 0 { + needExtra = false + for _, arg := range args { + switch arg { + case "CGO_CFLAGS", + "CGO_CPPFLAGS", + "CGO_CXXFLAGS", + "CGO_FFLAGS", + "CGO_LDFLAGS", + "PKG_CONFIG", + "GOGCCFLAGS": + needExtra = true + } + } + } + if needExtra { + env = append(env, ExtraEnvVars()...) + } + if len(args) > 0 { if *envJson { var es []cfg.EnvVar diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 385882b454..b652b71b4a 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -1232,30 +1232,39 @@ func (b *Builder) gccld(p *load.Package, objdir, out string, flags []string, obj return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, objs, flags) } +// Grab these before main helpfully overwrites them. +var ( + origCC = os.Getenv("CC") + origCXX = os.Getenv("CXX") +) + // gccCmd returns a gcc command line prefix // defaultCC is defined in zdefaultcc.go, written by cmd/dist. func (b *Builder) GccCmd(incdir, workdir string) []string { - return b.compilerCmd("CC", cfg.DefaultCC, incdir, workdir) + return b.compilerCmd(origCC, cfg.DefaultCC, incdir, workdir) } // gxxCmd returns a g++ command line prefix // defaultCXX is defined in zdefaultcc.go, written by cmd/dist. func (b *Builder) GxxCmd(incdir, workdir string) []string { - return b.compilerCmd("CXX", cfg.DefaultCXX, incdir, workdir) + return b.compilerCmd(origCXX, cfg.DefaultCXX, incdir, workdir) } // gfortranCmd returns a gfortran command line prefix. func (b *Builder) gfortranCmd(incdir, workdir string) []string { - return b.compilerCmd("FC", "gfortran", incdir, workdir) + return b.compilerCmd(os.Getenv("FC"), "gfortran", incdir, workdir) } // compilerCmd returns a command line prefix for the given environment // variable and using the default command when the variable is empty. -func (b *Builder) compilerCmd(envvar, defcmd, incdir, workdir string) []string { +func (b *Builder) compilerCmd(envValue, defcmd, incdir, workdir string) []string { // NOTE: env.go's mkEnv knows that the first three // strings returned are "gcc", "-I", incdir (and cuts them off). - compiler := envList(envvar, defcmd) + if envValue == "" { + envValue = defcmd + } + compiler := strings.Fields(envValue) a := []string{compiler[0], "-I", incdir} a = append(a, compiler[1:]...)