Skip to content

Commit

Permalink
go/tools/builders/pack: preserve file extensions (#1899)
Browse files Browse the repository at this point in the history
The .a format limits file names to 16 characters. There are various
extensions to this format which support longer names, but Go doesn't
recognize them and generally doesn't need them. Before Go 1.12, the
linker passed all extra files (other than the compiled Go code and the
export data) to the external link.

In Go 1.12, the linker only passes on .o files. The GoPack action
simply truncated long file names, which meant .o files were sometimes
ignored. GoPack will now preserve file extensions.

Updates #1896
  • Loading branch information
jayconrod authored and Jay Conrod committed Jan 19, 2019
1 parent fffe279 commit b445b49
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
1 change: 0 additions & 1 deletion go/private/rules/cgo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ def _cgo_codegen_impl(ctx):
mangled_stem, src_ext = _mangle(src, stems)
gen_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext)
transformed_go_outs.append(gen_file)
transformed_go_map[gen_go_file] = src
builder_args.add("-src", gen_file.path + "=" + src.path)
for src in source.c:
mangled_stem, src_ext = _mangle(src, stems)
Expand Down
28 changes: 18 additions & 10 deletions go/tools/builders/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,10 @@ func extractFiles(archive, dir string, names map[string]struct{}) (files []strin
}
continue
}
name = simpleName(name, names)
names[name] = struct{}{}
name, err = simpleName(name, names)
if err != nil {
return nil, err
}
name = filepath.Join(dir, name)
if err := extractFile(r, name, size); err != nil {
return nil, err
Expand Down Expand Up @@ -281,30 +283,36 @@ func isObjectFile(name string) bool {

// simpleName returns a file name which is at most 15 characters
// and doesn't conflict with other names. If it is not possible to choose
// such a name, simpleName will truncate the given name to 15 characters
func simpleName(name string, names map[string]struct{}) string {
// such a name, simpleName will truncate the given name to 15 characters.
// The original file extension will be preserved.
func simpleName(name string, names map[string]struct{}) (string, error) {
if _, ok := names[name]; !ok && len(name) < 16 {
return name
names[name] = struct{}{}
return name, nil
}
var stem, ext string
if i := strings.LastIndexByte(name, '.'); i < 0 || len(name)-i >= 10 {
if i := strings.LastIndexByte(name, '.'); i < 0 {
stem = name
} else {
stem = name[:i]
stem = strings.Replace(name[:i], ".", "_", -1)
ext = name[i:]
}
for n := 0; n < len(names); n++ {
for n := 0; n < len(names)+1; n++ {
ns := strconv.Itoa(n)
stemLen := 15 - len(ext) - len(ns)
if stemLen < 0 {
break
}
if stemLen > len(stem) {
stemLen = len(stem)
}
candidate := stem[:stemLen] + ns + ext
if _, ok := names[candidate]; !ok {
return candidate
names[candidate] = struct{}{}
return candidate, nil
}
}
return name[:15]
return "", fmt.Errorf("cannot shorten file name: %q", name)
}

func appendFiles(goenv *env, archive string, files []string) error {
Expand Down

0 comments on commit b445b49

Please sign in to comment.