2019-02-27 08:25:28 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package testcontext
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os/exec"
|
|
|
|
"path"
|
2019-06-13 16:09:05 +01:00
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
2019-06-15 12:23:12 +01:00
|
|
|
"testing"
|
2019-02-27 08:25:28 +00:00
|
|
|
)
|
|
|
|
|
2019-07-30 12:40:05 +01:00
|
|
|
// CLibMath is the standard C math library (see `man math.h`).
|
|
|
|
var CLibMath = Include{Standard: true, Library: "m"}
|
|
|
|
|
|
|
|
// CompileCOptions stores options for compiling C source to an executable.
|
|
|
|
type CompileCOptions struct {
|
|
|
|
Dest string
|
|
|
|
Sources []string
|
|
|
|
Includes []Include
|
|
|
|
NoWarn bool
|
|
|
|
}
|
|
|
|
|
2019-02-27 08:25:28 +00:00
|
|
|
// Compile compiles the specified package and returns the executable name.
|
|
|
|
func (ctx *Context) Compile(pkg string) string {
|
|
|
|
ctx.test.Helper()
|
|
|
|
|
|
|
|
exe := ctx.File("build", path.Base(pkg)+".exe")
|
|
|
|
|
|
|
|
var cmd *exec.Cmd
|
|
|
|
if raceEnabled {
|
|
|
|
cmd = exec.Command("go", "build", "-race", "-o", exe, pkg)
|
|
|
|
} else {
|
|
|
|
cmd = exec.Command("go", "build", "-o", exe, pkg)
|
|
|
|
}
|
2019-06-13 16:09:05 +01:00
|
|
|
ctx.test.Log("exec:", cmd.Args)
|
2019-02-27 08:25:28 +00:00
|
|
|
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
ctx.test.Error(string(out))
|
|
|
|
ctx.test.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return exe
|
|
|
|
}
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
// CompileShared compiles pkg as c-shared.
|
2019-06-15 12:23:12 +01:00
|
|
|
// TODO: support inclusion from other directories
|
|
|
|
// (cgo header paths are currently relative to package root)
|
|
|
|
func (ctx *Context) CompileShared(t *testing.T, name string, pkg string) Include {
|
|
|
|
t.Helper()
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
base := ctx.File("build", name)
|
|
|
|
|
|
|
|
// not using race detector for c-shared
|
|
|
|
cmd := exec.Command("go", "build", "-buildmode", "c-shared", "-o", base+".so", pkg)
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Log("exec:", cmd.Args)
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Error(string(out))
|
|
|
|
t.Fatal(err)
|
2019-06-13 16:09:05 +01:00
|
|
|
}
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Log(string(out))
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
return Include{Header: base + ".h", Library: base + ".so"}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CompileC compiles file as with gcc and adds the includes.
|
2019-07-30 12:40:05 +01:00
|
|
|
func (ctx *Context) CompileC(t *testing.T, opts CompileCOptions) string {
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Helper()
|
2019-06-13 16:09:05 +01:00
|
|
|
|
2019-07-30 12:40:05 +01:00
|
|
|
exe := ctx.File("build", opts.Dest+".exe")
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
var args = []string{}
|
2019-07-30 12:40:05 +01:00
|
|
|
if !opts.NoWarn {
|
|
|
|
args = append(args, "-Wall")
|
|
|
|
}
|
|
|
|
args = append(args, "-ggdb")
|
2019-06-13 16:09:05 +01:00
|
|
|
args = append(args, "-o", exe)
|
2019-07-30 12:40:05 +01:00
|
|
|
for _, inc := range opts.Includes {
|
2019-06-13 16:09:05 +01:00
|
|
|
if inc.Header != "" {
|
|
|
|
args = append(args, "-I", filepath.Dir(inc.Header))
|
|
|
|
}
|
|
|
|
if inc.Library != "" {
|
2019-06-21 13:24:06 +01:00
|
|
|
if inc.Standard {
|
|
|
|
args = append(args,
|
|
|
|
"-l"+inc.Library,
|
|
|
|
)
|
|
|
|
continue
|
|
|
|
}
|
2019-06-13 16:09:05 +01:00
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
args = append(args,
|
|
|
|
"-L"+filepath.Dir(inc.Library),
|
|
|
|
"-l:"+filepath.Base(inc.Library),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
args = append(args, inc.Library)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-30 12:40:05 +01:00
|
|
|
args = append(args, opts.Sources...)
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
cmd := exec.Command("gcc", args...)
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Log("exec:", cmd.Args)
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Error(string(out))
|
|
|
|
t.Fatal(err)
|
2019-06-13 16:09:05 +01:00
|
|
|
}
|
2019-06-15 12:23:12 +01:00
|
|
|
t.Log(string(out))
|
2019-06-13 16:09:05 +01:00
|
|
|
|
|
|
|
return exe
|
|
|
|
}
|
|
|
|
|
|
|
|
// Include defines an includable library for gcc.
|
|
|
|
type Include struct {
|
2019-06-21 13:24:06 +01:00
|
|
|
Header string
|
|
|
|
Library string
|
|
|
|
Standard bool
|
2019-06-13 16:09:05 +01:00
|
|
|
}
|