cmd/cgo: use objdir consistently, create it as needed

Previously we added a slash to the end of objdir only after
processing input files. The effect was that the temporary gcc
output files were placed in /tmp, using objdir as a prefix.
Those output files were not removed by anything.

Now we consistently use objdir as a directory, not a prefix.
We only create it when needed; there is already a test for that in
cmd/go/testdata/script/build_cwd_newline.txt.

Change-Id: Ie66d9c04ecc3c0f5950fc1111c74e1d01c67304c
Reviewed-on: https://go-review.googlesource.com/c/go/+/740742
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Ian Lance Taylor 2026-01-30 15:33:49 -08:00 committed by Gopher Robot
parent 1bbb78e777
commit 01299a31c2
4 changed files with 29 additions and 21 deletions

View file

@ -24,6 +24,7 @@ import (
"math"
"os"
"os/exec"
"path/filepath"
"slices"
"strconv"
"strings"
@ -1795,7 +1796,7 @@ var n atomic.Int64
func gccTmp() string {
c := strconv.Itoa(int(n.Add(1)))
return *objDir + "_cgo_" + c + ".o"
return filepath.Join(outputDir(), "_cgo_"+c+".o")
}
// gccCmd returns the gcc command line to use for compiling

View file

@ -320,6 +320,10 @@ func main() {
conf.Mode &^= printer.SourcePos
}
if *objDir == "" {
*objDir = "_obj"
}
args := flag.Args()
if len(args) < 1 {
usage()
@ -446,14 +450,6 @@ func main() {
cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
if *objDir == "" {
*objDir = "_obj"
}
// make sure that `objDir` directory exists, so that we can write
// all the output files there.
os.MkdirAll(*objDir, 0o700)
*objDir += string(filepath.Separator)
for i, input := range goFiles {
f := fs[i]
p.Translate(f)

View file

@ -33,15 +33,15 @@ var (
// writeDefs creates output files to be compiled by gc and gcc.
func (p *Package) writeDefs() {
var fgo2, fc io.Writer
f := creat(*objDir + "_cgo_gotypes.go")
f := creat("_cgo_gotypes.go")
defer f.Close()
fgo2 = f
if *gccgo {
f := creat(*objDir + "_cgo_defun.c")
f := creat("_cgo_defun.c")
defer f.Close()
fc = f
}
fm := creat(*objDir + "_cgo_main.c")
fm := creat("_cgo_main.c")
var gccgoInit strings.Builder
@ -50,7 +50,7 @@ func (p *Package) writeDefs() {
fmt.Fprintf(fgo2, "//go:cgo_ldflag %q\n", arg)
}
} else {
fflg := creat(*objDir + "_cgo_flags")
fflg := creat("_cgo_flags")
for _, arg := range p.LdFlags {
fmt.Fprintf(fflg, "_CGO_LDFLAGS=%s\n", arg)
}
@ -242,8 +242,8 @@ func (p *Package) writeDefs() {
}
}
fgcc := creat(*objDir + "_cgo_export.c")
fgcch := creat(*objDir + "_cgo_export.h")
fgcc := creat("_cgo_export.c")
fgcch := creat("_cgo_export.h")
if *gccgo {
p.writeGccgoExports(fgo2, fm, fgcc, fgcch)
} else {
@ -263,8 +263,11 @@ func (p *Package) writeDefs() {
}
if *exportHeader != "" && len(p.ExpFunc) > 0 {
fexp := creat(*exportHeader)
fgcch, err := os.Open(*objDir + "_cgo_export.h")
fexp, err := os.Create(*exportHeader)
if err != nil {
fatalf("%s", err)
}
fgcch, err := os.Open(filepath.Join(outputDir(), "_cgo_export.h"))
if err != nil {
fatalf("%s", err)
}
@ -697,8 +700,8 @@ func (p *Package) writeOutput(f *File, srcfile string) {
base := srcfile
base = strings.TrimSuffix(base, ".go")
base = filepath.Base(base)
fgo1 := creat(*objDir + base + ".cgo1.go")
fgcc := creat(*objDir + base + ".cgo2.c")
fgo1 := creat(base + ".cgo1.go")
fgcc := creat(base + ".cgo2.c")
p.GoFiles = append(p.GoFiles, base+".cgo1.go")
p.GccFiles = append(p.GccFiles, base+".cgo2.c")
@ -1395,7 +1398,7 @@ func gccgoToSymbol(ppath string) string {
fatalf("unable to locate gccgo: %v", err)
}
}
gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, *objDir)
gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, outputDir())
if err != nil {
fatalf("%v", err)
}

View file

@ -10,6 +10,7 @@ import (
"go/token"
"os"
"os/exec"
"path/filepath"
"slices"
)
@ -97,10 +98,17 @@ func error_(pos token.Pos, msg string, args ...any) {
fmt.Fprintf(os.Stderr, "\n")
}
// create creates a file in the output directory.
func creat(name string) *os.File {
f, err := os.Create(name)
f, err := os.Create(filepath.Join(outputDir(), name))
if err != nil {
fatalf("%s", err)
}
return f
}
// outputDir returns the output directory, making sure that it exists.
func outputDir() string {
os.MkdirAll(*objDir, 0o700)
return *objDir
}