Commit 2f55f4aa by Ian Lance Taylor Committed by Ian Lance Taylor

go/build, cmd/go: update to match recent changes to gc

    
    Several recent changes to the gc version of cmd/go improve the
    gofrontend support. These changes are partially copies of existing
    gofrontend differences, and partially new code. This CL makes the
    gofrontend match the upstream code.
    
    The changes included here come from:
        https://golang.org/cl/111575
        https://golang.org/cl/111595
        https://golang.org/cl/111635
        https://golang.org/cl/111636
    
    For the record, the following recent gc changes are based on code
    already present in the gofrontend repo:
        https://golang.org/cl/110915
        https://golang.org/cl/111615
    
    For the record, a gc change, partially based on earlier gofrontend
    work, also with new gc code, was already copied to gofrontend repo in
    CL 111099:
        https://golang.org/cl/111097
    
    This moves the generated list of standard library packages from
    cmd/go/internal/load to go/build.
    
    Reviewed-on: https://go-review.googlesource.com/112475

gotools/:
	* Makefile.am (check-go-tool): Don't copy zstdpkglist.go.
	* Makefile.in: Rebuild.

From-SVN: r260097
parent f2410266
6b0355769edd9543e6c5f2270b26b140bb96e9aa 290c93f08f4456f0552b0764e28573164e47f259
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
2018-05-09 Ian Lance Taylor <iant@golang.org>
* Makefile.am (check-go-tool): Don't copy zstdpkglist.go.
* Makefile.in: Rebuild.
2018-05-04 Ian Lance Taylor <iant@golang.org> 2018-05-04 Ian Lance Taylor <iant@golang.org>
PR go/85630 PR go/85630
......
...@@ -232,7 +232,6 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc ...@@ -232,7 +232,6 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc
$(MKDIR_P) check-go-dir/src/cmd/go $(MKDIR_P) check-go-dir/src/cmd/go
cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/ cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/
cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/ cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/
cp $(libgodir)/zstdpkglist.go check-go-dir/src/cmd/go/internal/load/
cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/
cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/ cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/
cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/ cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/
......
...@@ -637,8 +637,8 @@ distclean-generic: ...@@ -637,8 +637,8 @@ distclean-generic:
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
@NATIVE_FALSE@install-exec-local:
@NATIVE_FALSE@uninstall-local: @NATIVE_FALSE@uninstall-local:
@NATIVE_FALSE@install-exec-local:
clean: clean-am clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \
...@@ -811,7 +811,6 @@ mostlyclean-local: ...@@ -811,7 +811,6 @@ mostlyclean-local:
@NATIVE_TRUE@ $(MKDIR_P) check-go-dir/src/cmd/go @NATIVE_TRUE@ $(MKDIR_P) check-go-dir/src/cmd/go
@NATIVE_TRUE@ cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/
@NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/
@NATIVE_TRUE@ cp $(libgodir)/zstdpkglist.go check-go-dir/src/cmd/go/internal/load/
@NATIVE_TRUE@ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ @NATIVE_TRUE@ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/
@NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/
@NATIVE_TRUE@ cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/
......
...@@ -602,13 +602,13 @@ s-runtime-inc: runtime.lo Makefile ...@@ -602,13 +602,13 @@ s-runtime-inc: runtime.lo Makefile
$(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime.inc runtime.inc $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime.inc runtime.inc
$(STAMP) $@ $(STAMP) $@
noinst_DATA += zstdpkglist.go zdefaultcc.go noinst_DATA += zdefaultcc.go
# Generate the list of go std packages that were included in libgo # Generate the list of go std packages that were included in libgo
zstdpkglist.go: s-zstdpkglist; @true zstdpkglist.go: s-zstdpkglist; @true
s-zstdpkglist: Makefile s-zstdpkglist: Makefile
rm -f zstdpkglist.go.tmp rm -f zstdpkglist.go.tmp
echo 'package load' > zstdpkglist.go.tmp echo 'package build' > zstdpkglist.go.tmp
echo "" >> zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp
echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp
echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp
...@@ -960,6 +960,9 @@ runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline ...@@ -960,6 +960,9 @@ runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline
extra_go_files_runtime_internal_sys = version.go extra_go_files_runtime_internal_sys = version.go
runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys) runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys)
extra_go_files_go_build = zstdpkglist.go
go/build.lo.dep: $(extra_go_files_go_build)
extra_go_files_go_types = gccgosizes.go extra_go_files_go_types = gccgosizes.go
go/types.lo.dep: $(extra_go_files_go_types) go/types.lo.dep: $(extra_go_files_go_types)
...@@ -969,9 +972,6 @@ cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi) ...@@ -969,9 +972,6 @@ cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi)
extra_go_files_cmd_go_internal_cfg = zdefaultcc.go extra_go_files_cmd_go_internal_cfg = zdefaultcc.go
cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg) cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg)
extra_go_files_cmd_go_internal_load = zstdpkglist.go
cmd/go/internal/load.lo.dep: $(extra_go_files_cmd_go_internal_load)
extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a
extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a
extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a
......
...@@ -759,7 +759,7 @@ noinst_DATA = golang_org/x/net/internal/nettest.gox \ ...@@ -759,7 +759,7 @@ noinst_DATA = golang_org/x/net/internal/nettest.gox \
golang_org/x/net/nettest.gox internal/testenv.gox \ golang_org/x/net/nettest.gox internal/testenv.gox \
internal/trace.gox net/internal/socktest.gox \ internal/trace.gox net/internal/socktest.gox \
os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \
zstdpkglist.go zdefaultcc.go zdefaultcc.go
@LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file =
@LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c @LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c
...@@ -999,10 +999,10 @@ runtime_internal_sys_lo_check_GOCFLAGS = -fgo-compiling-runtime ...@@ -999,10 +999,10 @@ runtime_internal_sys_lo_check_GOCFLAGS = -fgo-compiling-runtime
# Also use -fno-inline to get better results from the memory profiler. # Also use -fno-inline to get better results from the memory profiler.
runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline
extra_go_files_runtime_internal_sys = version.go extra_go_files_runtime_internal_sys = version.go
extra_go_files_go_build = zstdpkglist.go
extra_go_files_go_types = gccgosizes.go extra_go_files_go_types = gccgosizes.go
extra_go_files_cmd_internal_objabi = objabi.go extra_go_files_cmd_internal_objabi = objabi.go
extra_go_files_cmd_go_internal_cfg = zdefaultcc.go extra_go_files_cmd_go_internal_cfg = zdefaultcc.go
extra_go_files_cmd_go_internal_load = zstdpkglist.go
extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a
extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a
extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a
...@@ -2816,7 +2816,7 @@ s-runtime-inc: runtime.lo Makefile ...@@ -2816,7 +2816,7 @@ s-runtime-inc: runtime.lo Makefile
zstdpkglist.go: s-zstdpkglist; @true zstdpkglist.go: s-zstdpkglist; @true
s-zstdpkglist: Makefile s-zstdpkglist: Makefile
rm -f zstdpkglist.go.tmp rm -f zstdpkglist.go.tmp
echo 'package load' > zstdpkglist.go.tmp echo 'package build' > zstdpkglist.go.tmp
echo "" >> zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp
echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp
echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp
...@@ -2943,10 +2943,10 @@ $(foreach package,$(GOTOOL_PACKAGES),$(eval $(call PACKAGE_template,$(package))) ...@@ -2943,10 +2943,10 @@ $(foreach package,$(GOTOOL_PACKAGES),$(eval $(call PACKAGE_template,$(package)))
runtime.lo.dep: $(extra_go_files_runtime) runtime.lo.dep: $(extra_go_files_runtime)
syscall.lo.dep: $(extra_go_files_syscall) syscall.lo.dep: $(extra_go_files_syscall)
runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys) runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys)
go/build.lo.dep: $(extra_go_files_go_build)
go/types.lo.dep: $(extra_go_files_go_types) go/types.lo.dep: $(extra_go_files_go_types)
cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi) cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi)
cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg) cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg)
cmd/go/internal/load.lo.dep: $(extra_go_files_cmd_go_internal_load)
# FIXME: The following C files may as well move to the runtime # FIXME: The following C files may as well move to the runtime
# directory and be treated like other C files. # directory and be treated like other C files.
......
...@@ -223,9 +223,6 @@ func (p *Package) copyBuild(pp *build.Package) { ...@@ -223,9 +223,6 @@ func (p *Package) copyBuild(pp *build.Package) {
// TODO? Target // TODO? Target
p.Goroot = pp.Goroot p.Goroot = pp.Goroot
p.Standard = p.Goroot && p.ImportPath != "" && isStandardImportPath(p.ImportPath) p.Standard = p.Goroot && p.ImportPath != "" && isStandardImportPath(p.ImportPath)
if cfg.BuildToolchainName == "gccgo" {
p.Standard = stdpkg[p.ImportPath]
}
p.GoFiles = pp.GoFiles p.GoFiles = pp.GoFiles
p.CgoFiles = pp.CgoFiles p.CgoFiles = pp.CgoFiles
p.IgnoredGoFiles = pp.IgnoredGoFiles p.IgnoredGoFiles = pp.IgnoredGoFiles
...@@ -894,13 +891,6 @@ var foldPath = make(map[string]string) ...@@ -894,13 +891,6 @@ var foldPath = make(map[string]string)
func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
p.copyBuild(bp) p.copyBuild(bp)
// When using gccgo the go/build package will not be able to
// find a standard package. It would be nicer to not get that
// error, but go/build doesn't know stdpkg.
if cfg.BuildToolchainName == "gccgo" && err != nil && p.Standard {
err = nil
}
// Decide whether p was listed on the command line. // Decide whether p was listed on the command line.
// Given that load is called while processing the command line, // Given that load is called while processing the command line,
// you might think we could simply pass a flag down into load // you might think we could simply pass a flag down into load
...@@ -1096,9 +1086,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { ...@@ -1096,9 +1086,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
continue continue
} }
p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], UseVendor) p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], UseVendor)
if cfg.BuildToolchainName == "gccgo" && p1.Standard {
continue
}
if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil { if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil {
p.Error = &PackageError{ p.Error = &PackageError{
ImportStack: stk.Copy(), ImportStack: stk.Copy(),
...@@ -1610,9 +1597,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err ...@@ -1610,9 +1597,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err
rawTestImports := str.StringList(p.TestImports) rawTestImports := str.StringList(p.TestImports)
for i, path := range p.TestImports { for i, path := range p.TestImports {
p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], UseVendor) p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], UseVendor)
if cfg.BuildToolchainName == "gccgo" && p1.Standard {
continue
}
if p1.Error != nil { if p1.Error != nil {
return nil, nil, p1.Error return nil, nil, p1.Error
} }
...@@ -1641,9 +1625,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err ...@@ -1641,9 +1625,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err
rawXTestImports := str.StringList(p.XTestImports) rawXTestImports := str.StringList(p.XTestImports)
for i, path := range p.XTestImports { for i, path := range p.XTestImports {
p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], UseVendor) p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], UseVendor)
if cfg.BuildToolchainName == "gccgo" && p1.Standard {
continue
}
if p1.Error != nil { if p1.Error != nil {
return nil, nil, p1.Error return nil, nil, p1.Error
} }
......
...@@ -633,6 +633,8 @@ func runTest(cmd *base.Command, args []string) { ...@@ -633,6 +633,8 @@ func runTest(cmd *base.Command, args []string) {
a := &work.Action{Mode: "go test -i"} a := &work.Action{Mode: "go test -i"}
for _, p := range load.PackagesForBuild(all) { for _, p := range load.PackagesForBuild(all) {
if cfg.BuildToolchainName == "gccgo" && p.Standard { if cfg.BuildToolchainName == "gccgo" && p.Standard {
// gccgo's standard library packages
// can not be reinstalled.
continue continue
} }
a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p)) a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
...@@ -862,9 +864,6 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin ...@@ -862,9 +864,6 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
pmain.Internal.Imports = append(pmain.Internal.Imports, ptest) pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
} else { } else {
p1 := load.LoadImport(dep, "", nil, &stk, nil, 0) p1 := load.LoadImport(dep, "", nil, &stk, nil, 0)
if cfg.BuildToolchainName == "gccgo" && p1.Standard {
continue
}
if p1.Error != nil { if p1.Error != nil {
return nil, nil, nil, p1.Error return nil, nil, nil, p1.Error
} }
......
...@@ -234,18 +234,9 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) { ...@@ -234,18 +234,9 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) {
// compile an empty file on standard input. // compile an empty file on standard input.
cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-") cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-")
cmd := exec.Command(cmdline[0], cmdline[1:]...) cmd := exec.Command(cmdline[0], cmdline[1:]...)
cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
// Strip any LANG or LC_ environment variables, and force // Force untranslated output so that we see the string "version".
// LANG=C, so that we get the untranslated output. cmd.Env = append(cmd.Env, "LC_ALL=C")
var env []string
for _, e := range os.Environ() {
if !strings.HasPrefix(e, "LANG=") && !strings.HasPrefix(e, "LC_") {
env = append(env, e)
}
}
env = append(env, "LANG=C")
cmd.Env = base.EnvForDir(cmd.Dir, env)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return "", fmt.Errorf("%s: %v; output: %q", name, err, out) return "", fmt.Errorf("%s: %v; output: %q", name, err, out)
......
...@@ -1545,6 +1545,8 @@ func joinUnambiguously(a []string) string { ...@@ -1545,6 +1545,8 @@ func joinUnambiguously(a []string) string {
buf.WriteByte(' ') buf.WriteByte(' ')
} }
q := strconv.Quote(s) q := strconv.Quote(s)
// A gccgo command line can contain -( and -).
// Make sure we quote them since they are special to the shell.
if s == "" || strings.ContainsAny(s, " ()") || len(q) > len(s)+2 { if s == "" || strings.ContainsAny(s, " ()") || len(q) > len(s)+2 {
buf.WriteString(q) buf.WriteString(q)
} else { } else {
...@@ -1585,13 +1587,17 @@ func (b *Builder) Mkdir(dir string) error { ...@@ -1585,13 +1587,17 @@ func (b *Builder) Mkdir(dir string) error {
// symlink creates a symlink newname -> oldname. // symlink creates a symlink newname -> oldname.
func (b *Builder) Symlink(oldname, newname string) error { func (b *Builder) Symlink(oldname, newname string) error {
// It's not an error to try to recreate an existing symlink.
if link, err := os.Readlink(newname); err == nil && link == oldname {
return nil
}
if cfg.BuildN || cfg.BuildX { if cfg.BuildN || cfg.BuildX {
b.Showcmd("", "ln -sf %s %s", oldname, newname) b.Showcmd("", "ln -s %s %s", oldname, newname)
if cfg.BuildN { if cfg.BuildN {
return nil return nil
} }
} }
os.Remove(newname)
return os.Symlink(oldname, newname) return os.Symlink(oldname, newname)
} }
......
...@@ -238,7 +238,7 @@ func (ctxt *Context) gopath() []string { ...@@ -238,7 +238,7 @@ func (ctxt *Context) gopath() []string {
// that do not exist. // that do not exist.
func (ctxt *Context) SrcDirs() []string { func (ctxt *Context) SrcDirs() []string {
var all []string var all []string
if ctxt.GOROOT != "" { if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
dir := ctxt.joinPath(ctxt.GOROOT, "src") dir := ctxt.joinPath(ctxt.GOROOT, "src")
if ctxt.isDir(dir) { if ctxt.isDir(dir) {
all = append(all, dir) all = append(all, dir)
...@@ -540,7 +540,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa ...@@ -540,7 +540,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
inTestdata := func(sub string) bool { inTestdata := func(sub string) bool {
return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata" return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata"
} }
if ctxt.GOROOT != "" { if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
root := ctxt.joinPath(ctxt.GOROOT, "src") root := ctxt.joinPath(ctxt.GOROOT, "src")
if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) { if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) {
p.Goroot = true p.Goroot = true
...@@ -557,7 +557,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa ...@@ -557,7 +557,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
// We found a potential import path for dir, // We found a potential import path for dir,
// but check that using it wouldn't find something // but check that using it wouldn't find something
// else first. // else first.
if ctxt.GOROOT != "" { if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) { if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
p.ConflictDir = dir p.ConflictDir = dir
goto Found goto Found
...@@ -622,7 +622,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa ...@@ -622,7 +622,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
} }
return false return false
} }
if searchVendor(ctxt.GOROOT, true) { if ctxt.Compiler != "gccgo" && searchVendor(ctxt.GOROOT, true) {
goto Found goto Found
} }
for _, root := range gopath { for _, root := range gopath {
...@@ -635,16 +635,24 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa ...@@ -635,16 +635,24 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
// Determine directory from import path. // Determine directory from import path.
if ctxt.GOROOT != "" { if ctxt.GOROOT != "" {
dir := ctxt.joinPath(ctxt.GOROOT, "src", path) dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
isDir := ctxt.isDir(dir) if ctxt.Compiler != "gccgo" {
binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) isDir := ctxt.isDir(dir)
if isDir || binaryOnly { binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
p.Dir = dir if isDir || binaryOnly {
p.Goroot = true p.Dir = dir
p.Root = ctxt.GOROOT p.Goroot = true
goto Found p.Root = ctxt.GOROOT
goto Found
}
} }
tried.goroot = dir tried.goroot = dir
} }
if ctxt.Compiler == "gccgo" && isStandardPackage(path) {
p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
p.Goroot = true
p.Root = ctxt.GOROOT
goto Found
}
for _, root := range gopath { for _, root := range gopath {
dir := ctxt.joinPath(root, "src", path) dir := ctxt.joinPath(root, "src", path)
isDir := ctxt.isDir(dir) isDir := ctxt.isDir(dir)
...@@ -708,6 +716,11 @@ Found: ...@@ -708,6 +716,11 @@ Found:
return p, pkgerr return p, pkgerr
} }
if ctxt.Compiler == "gccgo" && p.Goroot {
// gccgo has no sources for GOROOT packages.
return p, nil
}
dirs, err := ctxt.readDir(p.Dir) dirs, err := ctxt.readDir(p.Dir)
if err != nil { if err != nil {
return p, err return p, err
......
...@@ -7,11 +7,131 @@ ...@@ -7,11 +7,131 @@
package build package build
import ( import (
"os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
"sync"
) )
// getToolDir returns the default value of ToolDir. // getToolDir returns the default value of ToolDir.
func getToolDir() string { func getToolDir() string {
return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
} }
// isStandardPackage is not used for the gc toolchain.
// However, this function may be called when using `go build -compiler=gccgo`.
func isStandardPackage(path string) bool {
return gccgoSearch.isStandard(path)
}
// gccgoSearch holds the gccgo search directories.
type gccgoDirs struct {
once sync.Once
dirs []string
}
// gccgoSearch is used to check whether a gccgo package exists in the
// standard library.
var gccgoSearch gccgoDirs
// init finds the gccgo search directories. If this fails it leaves dirs == nil.
func (gd *gccgoDirs) init() {
gccgo := os.Getenv("GCCGO")
if gccgo == "" {
gccgo = "gccgo"
}
bin, err := exec.LookPath(gccgo)
if err != nil {
return
}
allDirs, err := exec.Command(bin, "-print-search-dirs").Output()
if err != nil {
return
}
versionB, err := exec.Command(bin, "-dumpversion").Output()
if err != nil {
return
}
version := strings.TrimSpace(string(versionB))
machineB, err := exec.Command(bin, "-dumpmachine").Output()
if err != nil {
return
}
machine := strings.TrimSpace(string(machineB))
dirsEntries := strings.Split(string(allDirs), "\n")
const prefix = "libraries: ="
var dirs []string
for _, dirEntry := range dirsEntries {
if strings.HasPrefix(dirEntry, prefix) {
dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix))
break
}
}
if len(dirs) == 0 {
return
}
var lastDirs []string
for _, dir := range dirs {
goDir := filepath.Join(dir, "go", version)
if fi, err := os.Stat(goDir); err == nil && fi.IsDir() {
gd.dirs = append(gd.dirs, goDir)
goDir = filepath.Join(goDir, machine)
if fi, err = os.Stat(goDir); err == nil && fi.IsDir() {
gd.dirs = append(gd.dirs, goDir)
}
}
if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
lastDirs = append(lastDirs, dir)
}
}
gd.dirs = append(gd.dirs, lastDirs...)
}
// isStandard returns whether path is a standard library for gccgo.
func (gd *gccgoDirs) isStandard(path string) bool {
// Quick check: if the first path component has a '.', it's not
// in the standard library. This skips most GOPATH directories.
i := strings.Index(path, "/")
if i < 0 {
i = len(path)
}
if strings.Contains(path[:i], ".") {
return false
}
if path == "unsafe" {
// Special case.
return true
}
gd.once.Do(gd.init)
if gd.dirs == nil {
// We couldn't find the gccgo search directories.
// Best guess, since the first component did not contain
// '.', is that this is a standard library package.
return true
}
for _, dir := range gd.dirs {
full := filepath.Join(dir, path)
pkgdir, pkg := filepath.Split(full)
for _, p := range [...]string{
full,
full + ".gox",
pkgdir + "lib" + pkg + ".so",
pkgdir + "lib" + pkg + ".a",
full + ".o",
} {
if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
return true
}
}
}
return false
}
...@@ -12,3 +12,9 @@ import "runtime" ...@@ -12,3 +12,9 @@ import "runtime"
func getToolDir() string { func getToolDir() string {
return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR) return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR)
} }
// isStandardPackage returns whether path names a standard library package.
// This uses a list generated at build time.
func isStandardPackage(path string) bool {
return stdpkg[path]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment