Commit 13d9a290 authored by Bryan C. Mills's avatar Bryan C. Mills

misc/cgo/testcarchive: fix tests in module mode

Updates #30228

Change-Id: I830e3c83416b2e5744f30d1a903a74c50462716b
Reviewed-on: https://go-review.googlesource.com/c/163210
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarJay Conrod <jayconrod@google.com>
parent 27b9571d
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"debug/elf" "debug/elf"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
...@@ -28,16 +29,41 @@ var bin []string ...@@ -28,16 +29,41 @@ var bin []string
// C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)). // C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)).
var cc []string var cc []string
// An environment with GOPATH=$(pwd).
var gopathEnv []string
// ".exe" on Windows. // ".exe" on Windows.
var exeSuffix string var exeSuffix string
var GOOS, GOARCH string var GOOS, GOARCH, GOPATH string
var libgodir string var libgodir string
func init() { func TestMain(m *testing.M) {
log.SetFlags(log.Lshortfile)
os.Exit(testMain(m))
}
func testMain(m *testing.M) int {
// We need a writable GOPATH in which to run the tests.
// Construct one in a temporary directory.
var err error
GOPATH, err = ioutil.TempDir("", "carchive_test")
if err != nil {
log.Panic(err)
}
defer os.RemoveAll(GOPATH)
os.Setenv("GOPATH", GOPATH)
// Copy testdata into GOPATH/src/testarchive, along with a go.mod file
// declaring the same path.
modRoot := filepath.Join(GOPATH, "src", "testcarchive")
if err := overlayDir(modRoot, "testdata"); err != nil {
log.Panic(err)
}
if err := os.Chdir(modRoot); err != nil {
log.Panic(err)
}
if err := ioutil.WriteFile("go.mod", []byte("module testcarchive\n"), 0666); err != nil {
log.Panic(err)
}
GOOS = goEnv("GOOS") GOOS = goEnv("GOOS")
GOARCH = goEnv("GOARCH") GOARCH = goEnv("GOARCH")
bin = cmdToRun("./testp") bin = cmdToRun("./testp")
...@@ -83,50 +109,36 @@ func init() { ...@@ -83,50 +109,36 @@ func init() {
// TODO(crawshaw): can we do better? // TODO(crawshaw): can we do better?
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...) cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
} }
libgodir = GOOS + "_" + GOARCH libbase := GOOS + "_" + GOARCH
if runtime.Compiler == "gccgo" { if runtime.Compiler == "gccgo" {
libgodir = "gccgo_" + libgodir + "_fPIC" libbase = "gccgo_" + libgodir + "_fPIC"
} else { } else {
switch GOOS { switch GOOS {
case "darwin": case "darwin":
if GOARCH == "arm" || GOARCH == "arm64" { if GOARCH == "arm" || GOARCH == "arm64" {
libgodir += "_shared" libbase += "_shared"
} }
case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
libgodir += "_shared" libbase += "_shared"
}
}
cc = append(cc, "-I", filepath.Join("pkg", libgodir))
// Build an environment with GOPATH=$(pwd)
env := os.Environ()
var n []string
for _, e := range env {
if !strings.HasPrefix(e, "GOPATH=") {
n = append(n, e)
} }
} }
dir, err := os.Getwd() libgodir = filepath.Join(GOPATH, "pkg", libbase, "testcarchive")
if err != nil { cc = append(cc, "-I", libgodir)
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
n = append(n, "GOPATH="+dir)
gopathEnv = n
if GOOS == "windows" { if GOOS == "windows" {
exeSuffix = ".exe" exeSuffix = ".exe"
} }
return m.Run()
} }
func goEnv(key string) string { func goEnv(key string) string {
out, err := exec.Command("go", "env", key).Output() out, err := exec.Command("go", "env", key).Output()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "go env %s failed:\n%s\n", key, err)
if ee, ok := err.(*exec.ExitError); ok { if ee, ok := err.(*exec.ExitError); ok {
fmt.Fprintf(os.Stderr, "%s", ee.Stderr) fmt.Fprintf(os.Stderr, "%s", ee.Stderr)
} }
os.Exit(2) log.Panicf("go env %s failed:\n%s\n", key, err)
} }
return strings.TrimSpace(string(out)) return strings.TrimSpace(string(out))
} }
...@@ -143,7 +155,6 @@ func cmdToRun(name string) []string { ...@@ -143,7 +155,6 @@ func cmdToRun(name string) []string {
func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
t.Helper() t.Helper()
cmd := exec.Command(buildcmd[0], buildcmd[1:]...) cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd) t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
...@@ -204,7 +215,7 @@ func checkLineComments(t *testing.T, hdrname string) { ...@@ -204,7 +215,7 @@ func checkLineComments(t *testing.T, hdrname string) {
} }
func TestInstall(t *testing.T) { func TestInstall(t *testing.T) {
defer os.RemoveAll("pkg") defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
libgoa := "libgo.a" libgoa := "libgo.a"
if runtime.Compiler == "gccgo" { if runtime.Compiler == "gccgo" {
...@@ -212,17 +223,17 @@ func TestInstall(t *testing.T) { ...@@ -212,17 +223,17 @@ func TestInstall(t *testing.T) {
} }
testInstall(t, "./testp1"+exeSuffix, testInstall(t, "./testp1"+exeSuffix,
filepath.Join("pkg", libgodir, libgoa), filepath.Join(libgodir, libgoa),
filepath.Join("pkg", libgodir, "libgo.h"), filepath.Join(libgodir, "libgo.h"),
"go", "install", "-i", "-buildmode=c-archive", "libgo") "go", "install", "-i", "-buildmode=c-archive", "./libgo")
// Test building libgo other than installing it. // Test building libgo other than installing it.
// Header files are now present. // Header files are now present.
testInstall(t, "./testp2"+exeSuffix, "libgo.a", "libgo.h", testInstall(t, "./testp2"+exeSuffix, "libgo.a", "libgo.h",
"go", "build", "-buildmode=c-archive", filepath.Join("src", "libgo", "libgo.go")) "go", "build", "-buildmode=c-archive", filepath.Join(".", "libgo", "libgo.go"))
testInstall(t, "./testp3"+exeSuffix, "libgo.a", "libgo.h", testInstall(t, "./testp3"+exeSuffix, "libgo.a", "libgo.h",
"go", "build", "-buildmode=c-archive", "-o", "libgo.a", "libgo") "go", "build", "-buildmode=c-archive", "-o", "libgo.a", "./libgo")
} }
func TestEarlySignalHandler(t *testing.T) { func TestEarlySignalHandler(t *testing.T) {
...@@ -240,11 +251,10 @@ func TestEarlySignalHandler(t *testing.T) { ...@@ -240,11 +251,10 @@ func TestEarlySignalHandler(t *testing.T) {
os.Remove("libgo2.a") os.Remove("libgo2.a")
os.Remove("libgo2.h") os.Remove("libgo2.h")
os.Remove("testp") os.Remove("testp")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -273,11 +283,10 @@ func TestSignalForwarding(t *testing.T) { ...@@ -273,11 +283,10 @@ func TestSignalForwarding(t *testing.T) {
os.Remove("libgo2.a") os.Remove("libgo2.a")
os.Remove("libgo2.h") os.Remove("libgo2.h")
os.Remove("testp") os.Remove("testp")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -317,11 +326,10 @@ func TestSignalForwardingExternal(t *testing.T) { ...@@ -317,11 +326,10 @@ func TestSignalForwardingExternal(t *testing.T) {
os.Remove("libgo2.a") os.Remove("libgo2.a")
os.Remove("libgo2.h") os.Remove("libgo2.h")
os.Remove("testp") os.Remove("testp")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -433,11 +441,10 @@ func TestOsSignal(t *testing.T) { ...@@ -433,11 +441,10 @@ func TestOsSignal(t *testing.T) {
os.Remove("libgo3.a") os.Remove("libgo3.a")
os.Remove("libgo3.h") os.Remove("libgo3.h")
os.Remove("testp") os.Remove("testp")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "libgo3") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -469,11 +476,10 @@ func TestSigaltstack(t *testing.T) { ...@@ -469,11 +476,10 @@ func TestSigaltstack(t *testing.T) {
os.Remove("libgo4.a") os.Remove("libgo4.a")
os.Remove("libgo4.h") os.Remove("libgo4.h")
os.Remove("testp") os.Remove("testp")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "libgo4") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -517,7 +523,7 @@ func TestExtar(t *testing.T) { ...@@ -517,7 +523,7 @@ func TestExtar(t *testing.T) {
os.Remove("libgo4.h") os.Remove("libgo4.h")
os.Remove("testar") os.Remove("testar")
os.Remove("testar.ran") os.Remove("testar.ran")
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
os.Remove("testar") os.Remove("testar")
...@@ -530,8 +536,7 @@ func TestExtar(t *testing.T) { ...@@ -530,8 +536,7 @@ func TestExtar(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "libgo4") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "./libgo4")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -555,11 +560,10 @@ func TestPIE(t *testing.T) { ...@@ -555,11 +560,10 @@ func TestPIE(t *testing.T) {
defer func() { defer func() {
os.Remove("testp" + exeSuffix) os.Remove("testp" + exeSuffix)
os.RemoveAll("pkg") os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}() }()
cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "libgo") cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "./libgo")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -570,7 +574,7 @@ func TestPIE(t *testing.T) { ...@@ -570,7 +574,7 @@ func TestPIE(t *testing.T) {
libgoa = "liblibgo.a" libgoa = "liblibgo.a"
} }
ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, libgoa)) ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join(libgodir, libgoa))
if runtime.Compiler == "gccgo" { if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo") ccArgs = append(ccArgs, "-lgo")
} }
...@@ -643,8 +647,7 @@ func TestSIGPROF(t *testing.T) { ...@@ -643,8 +647,7 @@ func TestSIGPROF(t *testing.T) {
os.Remove("libgo6.h") os.Remove("libgo6.h")
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "libgo6") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6")
cmd.Env = gopathEnv
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
...@@ -683,8 +686,7 @@ func TestCompileWithoutShared(t *testing.T) { ...@@ -683,8 +686,7 @@ func TestCompileWithoutShared(t *testing.T) {
os.Remove("libgo2.h") os.Remove("libgo2.h")
}() }()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "libgo2") cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2")
cmd.Env = gopathEnv
t.Log(cmd.Args) t.Log(cmd.Args)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
t.Logf("%s", out) t.Logf("%s", out)
...@@ -732,15 +734,14 @@ func TestCompileWithoutShared(t *testing.T) { ...@@ -732,15 +734,14 @@ func TestCompileWithoutShared(t *testing.T) {
// Test that installing a second time recreates the header files. // Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) { func TestCachedInstall(t *testing.T) {
defer os.RemoveAll("pkg") defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
h1 := filepath.Join("pkg", libgodir, "libgo.h") h1 := filepath.Join(libgodir, "libgo.h")
h2 := filepath.Join("pkg", libgodir, "p.h") h2 := filepath.Join(libgodir, "p.h")
buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"} buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "./libgo"}
cmd := exec.Command(buildcmd[0], buildcmd[1:]...) cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd) t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
...@@ -762,7 +763,6 @@ func TestCachedInstall(t *testing.T) { ...@@ -762,7 +763,6 @@ func TestCachedInstall(t *testing.T) {
} }
cmd = exec.Command(buildcmd[0], buildcmd[1:]...) cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd) t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
......
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package carchive_test
import (
"io"
"os"
"path/filepath"
"strings"
)
// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added.
//
// TODO: Once we no longer need to support the misc module in GOPATH mode,
// factor this function out into a package to reduce duplication.
func overlayDir(dstRoot, srcRoot string) error {
dstRoot = filepath.Clean(dstRoot)
if err := os.MkdirAll(dstRoot, 0777); err != nil {
return err
}
symBase, err := filepath.Rel(srcRoot, dstRoot)
if err != nil {
symBase, err = filepath.Abs(srcRoot)
if err != nil {
return err
}
}
return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error {
if err != nil || srcPath == srcRoot {
return err
}
suffix := strings.TrimPrefix(srcPath, srcRoot)
for len(suffix) > 0 && suffix[0] == filepath.Separator {
suffix = suffix[1:]
}
dstPath := filepath.Join(dstRoot, suffix)
perm := info.Mode() & os.ModePerm
if info.Mode()&os.ModeSymlink != 0 {
info, err = os.Stat(srcPath)
if err != nil {
return err
}
perm = info.Mode() & os.ModePerm
}
// Always copy directories (don't symlink them).
// If we add a file in the overlay, we don't want to add it in the original.
if info.IsDir() {
return os.Mkdir(dstPath, perm)
}
// If the OS supports symlinks, use them instead of copying bytes.
if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil {
return nil
}
// Otherwise, copy the bytes.
src, err := os.Open(srcPath)
if err != nil {
return err
}
defer src.Close()
dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
if err != nil {
return err
}
_, err = io.Copy(dst, src)
if closeErr := dst.Close(); err == nil {
err = closeErr
}
return err
})
}
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
"syscall" "syscall"
"time" "time"
_ "p" _ "testcarchive/p"
) )
import "C" import "C"
......
...@@ -692,7 +692,7 @@ func (t *tester) registerTests() { ...@@ -692,7 +692,7 @@ func (t *tester) registerTests() {
}) })
} }
if t.supportedBuildmode("c-archive") { if t.supportedBuildmode("c-archive") {
t.registerHostTest("testcarchive", "../misc/cgo/testcarchive", "misc/cgo/testcarchive", "carchive_test.go") t.registerHostTest("testcarchive", "../misc/cgo/testcarchive", "misc/cgo/testcarchive", ".")
} }
if t.supportedBuildmode("c-shared") { if t.supportedBuildmode("c-shared") {
t.registerHostTest("testcshared", "../misc/cgo/testcshared", "misc/cgo/testcshared", "cshared_test.go") t.registerHostTest("testcshared", "../misc/cgo/testcshared", "misc/cgo/testcshared", "cshared_test.go")
......
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