1
0
mirror of https://github.com/golang/go synced 2024-11-20 10:34:42 -07:00

cmd/go: special case shared library name when passed "$prefix/..."

Before golang.org/cl/13921, "go install -buildmode=shared prefix/..." created a
file called "libprefix.so", which was obviously a problem when prefix was
something like "." or "../".  However, now it expands the ... into all the
matched packages, joins them with -, which can clearly be a very long name
indeed. Because I plan to build shared libraries for Ubuntu by running commands
exactly like "go install -buildmode=shared prefix/...", this special cases this
to produce the old behaviour (but de-relativises prefix first).

Fixes #13714

Change-Id: I4fd8d4934279f9a18cc70a13e4ef3e23f6abcb6e
Reviewed-on: https://go-review.googlesource.com/18114
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Michael Hudson-Doyle 2015-12-23 15:33:55 +13:00
parent 7f96e266ec
commit ae8e55860b
2 changed files with 87 additions and 54 deletions

View File

@ -520,11 +520,14 @@ func isMetaPackage(name string) bool {
// Use arguments for special 'meta' packages: // Use arguments for special 'meta' packages:
// std --> libstd.so // std --> libstd.so
// std cmd --> libstd,cmd.so // std cmd --> libstd,cmd.so
// A single non-meta argument with trailing "/..." is special cased:
// foo/... --> libfoo.so
// (A relative path like "./..." expands the "." first)
// Use import paths for other cases, changing '/' to '-': // Use import paths for other cases, changing '/' to '-':
// somelib --> libsubdir-somelib.so // somelib --> libsubdir-somelib.so
// ./ or ../ --> libsubdir-somelib.so // ./ or ../ --> libsubdir-somelib.so
// gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so // gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
// ./... ---> libpkg1,pkg2.so - subset of all import paths // a/... b/... ---> liba/c,b/d.so - all matching import paths
// Name parts are joined with ','. // Name parts are joined with ','.
func libname(args []string, pkgs []*Package) (string, error) { func libname(args []string, pkgs []*Package) (string, error) {
var libname string var libname string
@ -544,9 +547,22 @@ func libname(args []string, pkgs []*Package) (string, error) {
} }
} }
if len(libname) == 0 { // non-meta packages only. use import paths if len(libname) == 0 { // non-meta packages only. use import paths
if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
// Special case of "foo/..." as mentioned above.
arg := strings.TrimSuffix(args[0], "/...")
if build.IsLocalImport(arg) {
cwd, _ := os.Getwd()
bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
if bp.ImportPath != "" && bp.ImportPath != "." {
arg = bp.ImportPath
}
}
appendName(strings.Replace(arg, "/", "-", -1))
} else {
for _, pkg := range pkgs { for _, pkg := range pkgs {
appendName(strings.Replace(pkg.ImportPath, "/", "-", -1)) appendName(strings.Replace(pkg.ImportPath, "/", "-", -1))
} }
}
} else if haveNonMeta { // have both meta package and a non-meta one } else if haveNonMeta { // have both meta package and a non-meta one
return "", errors.New("mixing of meta and non-meta packages is not allowed") return "", errors.New("mixing of meta and non-meta packages is not allowed")
} }

View File

@ -5,6 +5,9 @@
package main package main
import ( import (
"io/ioutil"
"os"
"path/filepath"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -90,73 +93,86 @@ func TestSharedLibName(t *testing.T) {
pkgs []*Package pkgs []*Package
expected string expected string
expectErr bool expectErr bool
rootedAt string
}{ }{
{ {
[]string{"std"}, args: []string{"std"},
[]*Package{}, pkgs: []*Package{},
"std", expected: "std",
false,
}, },
{ {
[]string{"std", "cmd"}, args: []string{"std", "cmd"},
[]*Package{}, pkgs: []*Package{},
"std,cmd", expected: "std,cmd",
false,
}, },
{ {
[]string{}, args: []string{},
[]*Package{&Package{ImportPath: "gopkg.in/somelib"}}, pkgs: []*Package{&Package{ImportPath: "gopkg.in/somelib"}},
"gopkg.in-somelib", expected: "gopkg.in-somelib",
false,
}, },
{ {
[]string{"./..."}, args: []string{"./..."},
[]*Package{&Package{ImportPath: "somelib"}}, pkgs: []*Package{&Package{ImportPath: "somelib"}},
"somelib", expected: "somelib",
false, rootedAt: "somelib",
}, },
{ {
[]string{"../somelib", "../somelib"}, args: []string{"../somelib", "../somelib"},
[]*Package{&Package{ImportPath: "somelib"}}, pkgs: []*Package{&Package{ImportPath: "somelib"}},
"somelib", expected: "somelib",
false,
}, },
{ {
[]string{"../lib1", "../lib2"}, args: []string{"../lib1", "../lib2"},
[]*Package{&Package{ImportPath: "gopkg.in/lib1"}, &Package{ImportPath: "gopkg.in/lib2"}}, pkgs: []*Package{&Package{ImportPath: "gopkg.in/lib1"}, &Package{ImportPath: "gopkg.in/lib2"}},
"gopkg.in-lib1,gopkg.in-lib2", expected: "gopkg.in-lib1,gopkg.in-lib2",
false,
}, },
{ {
[]string{"./..."}, args: []string{"./..."},
[]*Package{ pkgs: []*Package{
&Package{ImportPath: "gopkg.in/dir/lib1"}, &Package{ImportPath: "gopkg.in/dir/lib1"},
&Package{ImportPath: "gopkg.in/lib2"}, &Package{ImportPath: "gopkg.in/lib2"},
&Package{ImportPath: "gopkg.in/lib3"}, &Package{ImportPath: "gopkg.in/lib3"},
}, },
"gopkg.in-dir-lib1,gopkg.in-lib2,gopkg.in-lib3", expected: "gopkg.in",
false, rootedAt: "gopkg.in",
}, },
{ {
[]string{"std", "../lib2"}, args: []string{"std", "../lib2"},
[]*Package{}, pkgs: []*Package{},
"", expectErr: true,
true,
}, },
{ {
[]string{"all", "./"}, args: []string{"all", "./"},
[]*Package{}, pkgs: []*Package{},
"", expectErr: true,
true,
}, },
{ {
[]string{"cmd", "fmt"}, args: []string{"cmd", "fmt"},
[]*Package{}, pkgs: []*Package{},
"", expectErr: true,
true,
}, },
} }
for _, data := range testData { for _, data := range testData {
func() {
if data.rootedAt != "" {
tmpGopath, err := ioutil.TempDir("", "gopath")
if err != nil {
t.Fatal(err)
}
oldGopath := buildContext.GOPATH
defer func() {
os.RemoveAll(tmpGopath)
buildContext.GOPATH = oldGopath
os.Chdir(cwd)
}()
root := filepath.Join(tmpGopath, "src", data.rootedAt)
err = os.MkdirAll(root, 0755)
if err != nil {
t.Fatal(err)
}
buildContext.GOPATH = tmpGopath
os.Chdir(root)
}
computed, err := libname(data.args, data.pkgs) computed, err := libname(data.args, data.pkgs)
if err != nil { if err != nil {
if !data.expectErr { if !data.expectErr {
@ -170,5 +186,6 @@ func TestSharedLibName(t *testing.T) {
t.Errorf("libname returned %q, expected %q", computed, expected) t.Errorf("libname returned %q, expected %q", computed, expected)
} }
} }
}()
} }
} }