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 (
"debug/elf"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
......@@ -28,16 +29,41 @@ var bin []string
// C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)).
var cc []string
// An environment with GOPATH=$(pwd).
var gopathEnv []string
// ".exe" on Windows.
var exeSuffix string
var GOOS, GOARCH string
var GOOS, GOARCH, GOPATH 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")
GOARCH = goEnv("GOARCH")
bin = cmdToRun("./testp")
......@@ -83,50 +109,36 @@ func init() {
// TODO(crawshaw): can we do better?
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
}
libgodir = GOOS + "_" + GOARCH
libbase := GOOS + "_" + GOARCH
if runtime.Compiler == "gccgo" {
libgodir = "gccgo_" + libgodir + "_fPIC"
libbase = "gccgo_" + libgodir + "_fPIC"
} else {
switch GOOS {
case "darwin":
if GOARCH == "arm" || GOARCH == "arm64" {
libgodir += "_shared"
libbase += "_shared"
}
case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
libgodir += "_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)
libbase += "_shared"
}
}
dir, err := os.Getwd()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
n = append(n, "GOPATH="+dir)
gopathEnv = n
libgodir = filepath.Join(GOPATH, "pkg", libbase, "testcarchive")
cc = append(cc, "-I", libgodir)
if GOOS == "windows" {
exeSuffix = ".exe"
}
return m.Run()
}
func goEnv(key string) string {
out, err := exec.Command("go", "env", key).Output()
if err != nil {
fmt.Fprintf(os.Stderr, "go env %s failed:\n%s\n", key, err)
if ee, ok := err.(*exec.ExitError); ok {
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))
}
......@@ -143,7 +155,6 @@ func cmdToRun(name string) []string {
func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
t.Helper()
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
......@@ -204,7 +215,7 @@ func checkLineComments(t *testing.T, hdrname string) {
}
func TestInstall(t *testing.T) {
defer os.RemoveAll("pkg")
defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
libgoa := "libgo.a"
if runtime.Compiler == "gccgo" {
......@@ -212,17 +223,17 @@ func TestInstall(t *testing.T) {
}
testInstall(t, "./testp1"+exeSuffix,
filepath.Join("pkg", libgodir, libgoa),
filepath.Join("pkg", libgodir, "libgo.h"),
"go", "install", "-i", "-buildmode=c-archive", "libgo")
filepath.Join(libgodir, libgoa),
filepath.Join(libgodir, "libgo.h"),
"go", "install", "-i", "-buildmode=c-archive", "./libgo")
// Test building libgo other than installing it.
// Header files are now present.
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",
"go", "build", "-buildmode=c-archive", "-o", "libgo.a", "libgo")
"go", "build", "-buildmode=c-archive", "-o", "libgo.a", "./libgo")
}
func TestEarlySignalHandler(t *testing.T) {
......@@ -240,11 +251,10 @@ func TestEarlySignalHandler(t *testing.T) {
os.Remove("libgo2.a")
os.Remove("libgo2.h")
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.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -273,11 +283,10 @@ func TestSignalForwarding(t *testing.T) {
os.Remove("libgo2.a")
os.Remove("libgo2.h")
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.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -317,11 +326,10 @@ func TestSignalForwardingExternal(t *testing.T) {
os.Remove("libgo2.a")
os.Remove("libgo2.h")
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.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -433,11 +441,10 @@ func TestOsSignal(t *testing.T) {
os.Remove("libgo3.a")
os.Remove("libgo3.h")
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.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -469,11 +476,10 @@ func TestSigaltstack(t *testing.T) {
os.Remove("libgo4.a")
os.Remove("libgo4.h")
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.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -517,7 +523,7 @@ func TestExtar(t *testing.T) {
os.Remove("libgo4.h")
os.Remove("testar")
os.Remove("testar.ran")
os.RemoveAll("pkg")
os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}()
os.Remove("testar")
......@@ -530,8 +536,7 @@ func TestExtar(t *testing.T) {
t.Fatal(err)
}
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "libgo4")
cmd.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "./libgo4")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -555,11 +560,10 @@ func TestPIE(t *testing.T) {
defer func() {
os.Remove("testp" + exeSuffix)
os.RemoveAll("pkg")
os.RemoveAll(filepath.Join(GOPATH, "pkg"))
}()
cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "libgo")
cmd.Env = gopathEnv
cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "./libgo")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -570,7 +574,7 @@ func TestPIE(t *testing.T) {
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" {
ccArgs = append(ccArgs, "-lgo")
}
......@@ -643,8 +647,7 @@ func TestSIGPROF(t *testing.T) {
os.Remove("libgo6.h")
}()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "libgo6")
cmd.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6")
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
......@@ -683,8 +686,7 @@ func TestCompileWithoutShared(t *testing.T) {
os.Remove("libgo2.h")
}()
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "libgo2")
cmd.Env = gopathEnv
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2")
t.Log(cmd.Args)
out, err := cmd.CombinedOutput()
t.Logf("%s", out)
......@@ -732,15 +734,14 @@ func TestCompileWithoutShared(t *testing.T) {
// Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) {
defer os.RemoveAll("pkg")
defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
h1 := filepath.Join("pkg", libgodir, "libgo.h")
h2 := filepath.Join("pkg", libgodir, "p.h")
h1 := filepath.Join(libgodir, "libgo.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.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
......@@ -762,7 +763,6 @@ func TestCachedInstall(t *testing.T) {
}
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
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 (
"syscall"
"time"
_ "p"
_ "testcarchive/p"
)
import "C"
......
......@@ -692,7 +692,7 @@ func (t *tester) registerTests() {
})
}
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") {
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