diff --git a/go/tools/builders/compilepkg.go b/go/tools/builders/compilepkg.go index 4af57a774b..a5433665b5 100644 --- a/go/tools/builders/compilepkg.go +++ b/go/tools/builders/compilepkg.go @@ -404,11 +404,11 @@ func compileArchive( // 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): Ideally, we would use -linkobj to tell the compiler - // to create separate .a and .x files for compiled code and export data, then - // copy the nogo facts into the .x file. Unfortunately, when building a plugin, - // the linker needs export data in the .a file. To work around this, we copy - // the export data into the .x file ourselves. + // 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 } diff --git a/go/tools/builders/pack.go b/go/tools/builders/pack.go index 1bf23425b2..2a263e0d18 100644 --- a/go/tools/builders/pack.go +++ b/go/tools/builders/pack.go @@ -347,6 +347,23 @@ func simpleName(name string, names map[string]struct{}) (string, error) { } func appendFiles(goenv *env, archive string, files []string) error { + // Create an empty archive if one doesn't already exist. + // In Go 1.16, 'go tool pack r' reports an error if the archive doesn't exist. + // 'go tool pack c' copies export data in addition to creating the archive, + // so we don't want to use that directly. + _, err := os.Stat(archive) + if err != nil && !os.IsNotExist(err) { + return err + } + if os.IsNotExist(err) { + if err := ioutil.WriteFile(archive, []byte(arHeader), 0666); err != nil { + return err + } + } + + // Append files to the archive. + // TODO(jayconrod): copy cmd/internal/archive and use that instead of + // shelling out to cmd/pack. args := goenv.goTool("pack", "r", archive) args = append(args, files...) return goenv.runCommand(args)