Skip to content

Commit

Permalink
Use -linkobj to directly generate .x and .a
Browse files Browse the repository at this point in the history
  • Loading branch information
fmeum committed Dec 16, 2023
1 parent d5bc6ad commit c428f7f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 57 deletions.
34 changes: 11 additions & 23 deletions go/tools/builders/compilepkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func compilePkg(args []string) error {
var unfilteredSrcs, coverSrcs, embedSrcs, embedLookupDirs, embedRoots, recompileInternalDeps multiFlag
var deps archiveMultiFlag
var importPath, packagePath, nogoPath, packageListPath, coverMode string
var outPath, outFactsPath, cgoExportHPath string
var outPath, outXPath, cgoExportHPath string
var testFilter string
var gcFlags, asmFlags, cppFlags, cFlags, cxxFlags, objcFlags, objcxxFlags, ldFlags quoteMultiFlag
var coverFormat string
Expand All @@ -76,8 +76,8 @@ func compilePkg(args []string) error {
fs.StringVar(&nogoPath, "nogo", "", "The nogo binary. If unset, nogo will not be run.")
fs.StringVar(&packageListPath, "package_list", "", "The file containing the list of standard library packages")
fs.StringVar(&coverMode, "cover_mode", "", "The coverage mode to use. Empty if coverage instrumentation should not be added.")
fs.StringVar(&outPath, "o", "", "The output archive file to write compiled code")
fs.StringVar(&outFactsPath, "x", "", "The output archive file to write export data and nogo facts")
fs.StringVar(&outPath, "o", "", "The full output archive file required by the linker")
fs.StringVar(&outXPath, "x", "", "The export-only output archive required to compile dependent packages (may includes nogo facts)")
fs.StringVar(&cgoExportHPath, "cgoexport", "", "The _cgo_exports.h file to write")
fs.StringVar(&testFilter, "testfilter", "off", "Controls test package filtering")
fs.StringVar(&coverFormat, "cover_format", "", "Emit source file paths in coverage instrumentation suitable for the specified coverage format")
Expand Down Expand Up @@ -160,7 +160,7 @@ func compilePkg(args []string) error {
nogoPath,
packageListPath,
outPath,
outFactsPath,
outXPath,
cgoExportHPath,
coverFormat,
recompileInternalDeps,
Expand Down Expand Up @@ -483,7 +483,7 @@ func compileArchive(
}

// Compile the filtered .go files.
if err := compileGo(goenv, goSrcs, packagePath, importcfgPath, embedcfgPath, asmHdrPath, symabisPath, gcFlags, pgoprofile, outPath); err != nil {
if err := compileGo(goenv, goSrcs, packagePath, importcfgPath, embedcfgPath, asmHdrPath, symabisPath, gcFlags, pgoprofile, outPath, outXPath); err != nil {
return err
}

Expand Down Expand Up @@ -517,7 +517,7 @@ func compileArchive(
// Pack .o files into the archive. These may come from cgo generated code,
// cgo dependencies (cdeps), or assembly.
if len(objFiles) > 0 {
if err := appendFiles(goenv, outPath, objFiles); err != nil {
if err := appendFiles(goenv, outPath, objFiles...); err != nil {
return err
}
}
Expand All @@ -535,26 +535,13 @@ func compileArchive(
nogoStatus = nogoSucceeded
}

// Extract the export data file and pack it in an .x archive together with the
// nogo facts file (if there is one). This allows compile actions to depend
// on .x files only, so we don't need to recompile a package when one of its
// imports changes in a way that doesn't affect export data.
// TODO(golang/go#33820): After Go 1.16 is the minimum supported version,
// use -linkobj to tell the compiler to create separate .a and .x files for
// compiled code and export data. Before that version, the linker needed
// export data in the .a file when building a plugin. To work around that,
// we copy the export data into .x ourselves.
if err = extractFileFromArchive(outPath, workDir, pkgDef); err != nil {
return err
}
pkgDefPath := filepath.Join(workDir, pkgDef)
if nogoStatus == nogoSucceeded {
return appendFiles(goenv, outXPath, []string{pkgDefPath, outFactsPath})
return appendFiles(goenv, outXPath, outFactsPath)
}
return appendFiles(goenv, outXPath, []string{pkgDefPath})
return nil
}

func compileGo(goenv *env, srcs []string, packagePath, importcfgPath, embedcfgPath, asmHdrPath, symabisPath string, gcFlags []string, pgoprofile string, outPath string) error {
func compileGo(goenv *env, srcs []string, packagePath, importcfgPath, embedcfgPath, asmHdrPath, symabisPath string, gcFlags []string, pgoprofile, outPath, outXPath string) error {
args := goenv.goTool("compile")
args = append(args, "-p", packagePath, "-importcfg", importcfgPath, "-pack")
if embedcfgPath != "" {
Expand All @@ -570,7 +557,8 @@ func compileGo(goenv *env, srcs []string, packagePath, importcfgPath, embedcfgPa
args = append(args, "-pgoprofile", pgoprofile)
}
args = append(args, gcFlags...)
args = append(args, "-o", outPath)
args = append(args, "-o", outXPath)
args = append(args, "-linkobj", outPath)
args = append(args, "--")
args = append(args, srcs...)
absArgs(args, []string{"-I", "-o", "-trimpath", "-importcfg"})
Expand Down
35 changes: 1 addition & 34 deletions go/tools/builders/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ const (
// in an archive.
entryLength = 60

// pkgDef is the name of the export data file within an archive
pkgDef = "__.PKGDEF"

// nogoFact is the name of the nogo fact file
nogoFact = "nogo.out"
)
Expand Down Expand Up @@ -295,7 +292,7 @@ func simpleName(name string, names map[string]struct{}) (string, error) {
return "", fmt.Errorf("cannot shorten file name: %q", name)
}

func appendFiles(goenv *env, archive string, files []string) error {
func appendFiles(goenv *env, archive string, files ...string) error {
archive = abs(archive) // required for long filenames on Windows.

// Create an empty archive if one doesn't already exist.
Expand Down Expand Up @@ -356,33 +353,3 @@ func readFileInArchive(fileName, archive string) (io.ReadCloser, error) {
rc.Close()
return nil, err
}

func extractFileFromArchive(archive, dir, name string) (err error) {
archiveReader, err := readFileInArchive(name, archive)
if err != nil {
return fmt.Errorf("error reading %s from %s: %v", name, archive, err)
}
defer func() {
e := archiveReader.Close()
if e != nil && err == nil {
err = fmt.Errorf("error closing %q: %v", archive, e)
}
}()
outPath := filepath.Join(dir, pkgDef)
outFile, err := os.Create(outPath)
if err != nil {
return fmt.Errorf("error creating %s: %v", outPath, err)
}
defer func() {
e := outFile.Close()
if e != nil && err == nil {
err = fmt.Errorf("error closing %q: %v", outPath, e)
}
}()
if size, err := io.Copy(outFile, archiveReader); err != nil {
return fmt.Errorf("error writing %s: %v", outPath, err)
} else if size == 0 {
return fmt.Errorf("%s is empty in %s", name, archive)
}
return err
}

0 comments on commit c428f7f

Please sign in to comment.