aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/build.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/build.go')
-rw-r--r--src/cmd/go/build.go85
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)