diff options
Diffstat (limited to 'src/cmd/go/build.go')
-rw-r--r-- | src/cmd/go/build.go | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index cad578daed..0d161a7b01 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1670,26 +1670,35 @@ func splitPkgConfigOutput(out []byte) []string { // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) { if pkgs := p.CgoPkgConfig; len(pkgs) > 0 { + for _, pkg := range pkgs { + if !SafeArg(pkg) { + return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg) + } + } var out []byte - out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--cflags", pkgs) + out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--cflags", "--", pkgs) if err != nil { b.showOutput(p.Dir, b.pkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out)) b.print(err.Error() + "\n") - err = errPrintedOutput - return + return nil, nil, errPrintedOutput } if len(out) > 0 { cflags = splitPkgConfigOutput(out) + if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil { + return nil, nil, err + } } - out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--libs", pkgs) + out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--libs", "--", pkgs) if err != nil { b.showOutput(p.Dir, b.pkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out)) b.print(err.Error() + "\n") - err = errPrintedOutput - return + return nil, nil, errPrintedOutput } if len(out) > 0 { ldflags = strings.Fields(string(out)) + if err := checkLinkerFlags("CFLAGS", "pkg-config --cflags", ldflags); err != nil { + return nil, nil, err + } } } return @@ -2117,6 +2126,17 @@ func (b *builder) processOutput(out []byte) string { // It returns the command output and any errors that occurred. func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) { cmdline := stringList(cmdargs...) + + for _, arg := range cmdline { + // GNU binutils commands, including gcc and gccgo, interpret an argument + // @foo anywhere in the command line (even following --) as meaning + // "read and insert arguments from the file named foo." + // Don't say anything that might be misinterpreted that way. + if strings.HasPrefix(arg, "@") { + return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline)) + } + } + if buildN || buildX { var envcmdline string for i := range env { @@ -2357,6 +2377,9 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, // additional reflect type data. gcargs = append(gcargs, "-+") } + if p.Standard { + gcargs = append(gcargs, "-std") + } // If we're giving the compiler the entire package (no C etc files), tell it that, // so that it can give good error messages about forward declarations. @@ -3255,23 +3278,45 @@ func envList(key, def string) []string { return strings.Fields(v) } -// Return the flags to use when invoking the C, C++ or Fortran compilers, or cgo. -func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) { +// CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo. +func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) { defaults := "-g -O2" - cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) - cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) - cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) - fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS) - ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) + if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil { + return + } + if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil { + return + } + if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil { + return + } + if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil { + return + } + if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil { + return + } + return } +func buildFlags(name, defaults string, fromPackage []string, check func(string, string, []string) error) ([]string, error) { + if err := check(name, "#cgo "+name, fromPackage); err != nil { + return nil, err + } + return stringList(envList("CGO_"+name, defaults), fromPackage), nil +} + var cgoRe = regexp.MustCompile(`[/\\:]`) func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) { p := a.p - cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.cflags(p) + cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.cflags(p) + if err != nil { + return nil, nil, err + } + cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...) // If we are compiling Objective-C code, then we need to link against libobjc @@ -3335,6 +3380,12 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil } // Update $CGO_LDFLAGS with p.CgoLDFLAGS. + // These flags are recorded in the generated _cgo_gotypes.go file + // using //go:cgo_ldflag directives, the compiler records them in the + // object file for the package, and then the Go linker passes them + // along to the host linker. At this point in the code, cgoLDFLAGS + // consists of the original $CGO_LDFLAGS (unchecked) and all the + // flags put together from source code (checked). var cgoenv []string if len(cgoLDFLAGS) > 0 { flags := make([]string, len(cgoLDFLAGS)) @@ -3684,7 +3735,11 @@ func (b *builder) swigIntSize(obj string) (intsize string, err error) { // Run SWIG on one SWIG input file. func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) { - cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p) + cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.cflags(p) + if err != nil { + return "", "", err + } + var cflags []string if cxx { cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS) |