From 644da2d2357b7ad0c9fb4b72995bf0b526fc4cf4 Mon Sep 17 00:00:00 2001 From: xhd2015 Date: Thu, 11 Jul 2024 21:28:14 +0800 Subject: [PATCH] fix cross compile --- cmd/xgo/go_build.go | 41 +++++++++++++++++++++++++ cmd/xgo/patch.go | 24 +-------------- cmd/xgo/patch_compiler.go | 4 +-- cmd/xgo/shadow.go | 8 ++--- cmd/xgo/version.go | 4 +-- runtime/test/build/cross_build_test.go | 19 ++++++++++++ runtime/test/build/simple/greet.go | 7 +++++ runtime/test/build/simple/greet_test.go | 7 +++++ script/run-test/main.go | 26 +++++++++++----- 9 files changed, 101 insertions(+), 39 deletions(-) create mode 100644 cmd/xgo/go_build.go create mode 100644 runtime/test/build/cross_build_test.go create mode 100644 runtime/test/build/simple/greet.go create mode 100644 runtime/test/build/simple/greet_test.go diff --git a/cmd/xgo/go_build.go b/cmd/xgo/go_build.go new file mode 100644 index 00000000..7589c952 --- /dev/null +++ b/cmd/xgo/go_build.go @@ -0,0 +1,41 @@ +package main + +import ( + "os" + "os/exec" + "path/filepath" +) + +func buildCompiler(goroot string, output string) error { + args := []string{"build"} + if isDevelopment { + args = append(args, "-gcflags=all=-N -l") + } + args = append(args, "-o", output, "./") + cmd := exec.Command(filepath.Join(goroot, "bin", "go"), args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + env, err := patchEnvWithGoroot(os.Environ(), goroot) + if err != nil { + return err + } + cmd.Env = env + // when building the compiler, we want native + // build, see https://github.com/xhd2015/xgo/issues/231 + cmd.Env = appendNativeBuildEnv(cmd.Env) + cmd.Dir = filepath.Join(goroot, "src", "cmd", "compile") + return cmd.Run() +} +func buildExecTool(dir string, execToolBin string) error { + // build exec tool + cmd := exec.Command(getNakedGo(), "build", "-o", execToolBin, "./exec_tool") + cmd.Dir = dir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Env = appendNativeBuildEnv(os.Environ()) + return cmd.Run() +} + +func appendNativeBuildEnv(env []string) []string { + return append(env, "GOOS=", "GOARCH=") +} diff --git a/cmd/xgo/patch.go b/cmd/xgo/patch.go index 33a8382c..64cdb772 100644 --- a/cmd/xgo/patch.go +++ b/cmd/xgo/patch.go @@ -230,12 +230,7 @@ func buildInstrumentTool(goroot string, xgoSrc string, compilerBin string, compi if false { actualExecToolBin := execToolBin if isDevelopment { - // build exec tool - buildExecToolCmd := exec.Command(getNakedGo(), "build", "-o", execToolBin, "./exec_tool") - buildExecToolCmd.Dir = filepath.Join(xgoSrc, "cmd") - buildExecToolCmd.Stdout = os.Stdout - buildExecToolCmd.Stderr = os.Stderr - err = buildExecToolCmd.Run() + err := buildExecTool(filepath.Join(xgoSrc, "cmd"), execToolBin) if err != nil { return false, "", err } @@ -297,23 +292,6 @@ func findBuiltExecTool() (string, error) { } return "", fmt.Errorf("exec_tool not found in %s and ~/.xgo/bin", dirName) } -func buildCompiler(goroot string, output string) error { - args := []string{"build"} - if isDevelopment { - args = append(args, "-gcflags=all=-N -l") - } - args = append(args, "-o", output, "./") - cmd := exec.Command(filepath.Join(goroot, "bin", "go"), args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - env, err := patchEnvWithGoroot(os.Environ(), goroot) - if err != nil { - return err - } - cmd.Env = env - cmd.Dir = filepath.Join(goroot, "src", "cmd", "compile") - return cmd.Run() -} func compareAndUpdateCompilerID(compilerFile string, compilerIDFile string) (changed bool, err error) { prevData, statErr := fileutil.ReadFile(compilerIDFile) diff --git a/cmd/xgo/patch_compiler.go b/cmd/xgo/patch_compiler.go index fe011b84..08b10a6c 100644 --- a/cmd/xgo/patch_compiler.go +++ b/cmd/xgo/patch_compiler.go @@ -471,11 +471,11 @@ func patchRuntimeDef(origGoroot string, goroot string, goVersion *goinfo.GoVersi dirs = []string{goroot, "src", "cmd", "compile", "internal", "gc"} } cmd.Dir = filepath.Join(dirs...) - cmd.Env = os.Environ() - cmd.Env, err = patchEnvWithGoroot(cmd.Env, origGoroot) + cmd.Env, err = patchEnvWithGoroot(os.Environ(), origGoroot) if err != nil { return err } + cmd.Env = appendNativeBuildEnv(cmd.Env) err = cmd.Run() if err != nil { diff --git a/cmd/xgo/shadow.go b/cmd/xgo/shadow.go index e2a79d9e..6d41e2c2 100644 --- a/cmd/xgo/shadow.go +++ b/cmd/xgo/shadow.go @@ -3,11 +3,11 @@ package main import ( "embed" "fmt" - "io/ioutil" "os" "path/filepath" "github.com/xhd2015/xgo/support/cmd" + "github.com/xhd2015/xgo/support/fileutil" "github.com/xhd2015/xgo/support/osinfo" ) @@ -37,15 +37,15 @@ func handleShadow() error { return err } - err = ioutil.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(`module github.com/xhd2015/xgo/cmd/xgo/shadow + err = fileutil.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(`module github.com/xhd2015/xgo/cmd/xgo/shadow go 1.14 -`), 0755) +`)) if err != nil { return err } - err = cmd.Dir(tmpDir).Run(getNakedGo(), "build", "-o", filepath.Join(shadowDir, "go"+osinfo.EXE_SUFFIX), "./") + err = cmd.Dir(tmpDir).Env(appendNativeBuildEnv(nil)).Run(getNakedGo(), "build", "-o", filepath.Join(shadowDir, "go"+osinfo.EXE_SUFFIX), "./") if err != nil { return err } diff --git a/cmd/xgo/version.go b/cmd/xgo/version.go index fa541ce8..2eaae839 100644 --- a/cmd/xgo/version.go +++ b/cmd/xgo/version.go @@ -4,8 +4,8 @@ import "fmt" // auto updated const VERSION = "1.0.46" -const REVISION = "ab32ad121c57c321089d61906f2dd36898b7bcd1+1" -const NUMBER = 294 +const REVISION = "b2c1918871f0a8bc3ea4bb9cf46e297d21c5f433+1" +const NUMBER = 295 // manually updated const CORE_VERSION = "1.0.43" diff --git a/runtime/test/build/cross_build_test.go b/runtime/test/build/cross_build_test.go new file mode 100644 index 00000000..ac70d1c6 --- /dev/null +++ b/runtime/test/build/cross_build_test.go @@ -0,0 +1,19 @@ +package xgo_integration + +import ( + "testing" +) + +// go test ./test/xgo_integration/ -v -run TestCrossBuild +func TestCrossBuild(t *testing.T) { + // xgo test -c ./simple + + // _, err := exec.LookPath("xgo") + // if err != nil { + // t.Skipf("missing: %v", err) + // } + // err = cmd.Env([]string{"GOOS=windows", "GOARCH=amd64"}).Debug().Dir("./testdata/build_simple").Run("xgo", "test", "--log-debug", "-c", "-o", "/dev/null") + // if err != nil { + // t.Fatal(err) + // } +} diff --git a/runtime/test/build/simple/greet.go b/runtime/test/build/simple/greet.go new file mode 100644 index 00000000..1d5a82ca --- /dev/null +++ b/runtime/test/build/simple/greet.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Printf("hello xgo\n") +} diff --git a/runtime/test/build/simple/greet_test.go b/runtime/test/build/simple/greet_test.go new file mode 100644 index 00000000..9349134c --- /dev/null +++ b/runtime/test/build/simple/greet_test.go @@ -0,0 +1,7 @@ +package main + +import "testing" + +func TestHelloWorld(t *testing.T) { + t.Logf("hello world") +} diff --git a/script/run-test/main.go b/script/run-test/main.go index b8e4bac1..1aa43c38 100644 --- a/script/run-test/main.go +++ b/script/run-test/main.go @@ -68,6 +68,7 @@ type TestCase struct { dir string flags []string windowsFlags []string + env []string } var extraSubTests = []*TestCase{ @@ -154,6 +155,13 @@ var extraSubTests = []*TestCase{ dir: "runtime/test/mock/rule", flags: []string{"-run", "TestClosureWithMockRuleNoMock", "--mock-rule", `{"closure":true,"action":"exclude"}`}, }, + { + // see https://github.com/xhd2015/xgo/issues/231 + name: "cross_build", + dir: "runtime/test/build/simple", + flags: []string{"-c", "-o", "/dev/null"}, + env: []string{"GOOS=", "GOARCH="}, + }, { name: "xgo_integration", usePlainGo: true, @@ -473,15 +481,15 @@ func listGoroots(dir string) ([]string, error) { } func runDefaultTest(goroot string, args []string, tests []string) error { - return doRunTest(goroot, testKind_default, false, "", args, tests) + return doRunTest(goroot, testKind_default, false, "", args, tests, nil) } func runXgoTest(goroot string, args []string, tests []string) error { - return doRunTest(goroot, testKind_xgoTest, false, "", args, tests) + return doRunTest(goroot, testKind_xgoTest, false, "", args, tests, nil) } func runRuntimeTest(goroot string, args []string, tests []string) error { - err := doRunTest(goroot, testKind_runtimeTest, false, "", args, tests) + err := doRunTest(goroot, testKind_runtimeTest, false, "", args, tests, nil) if err != nil { return err } @@ -513,6 +521,7 @@ func runRuntimeSubTest(goroot string, args []string, tests []string, names []str continue } dir := tt.dir + env := tt.env var subDirs bool if strings.HasSuffix(dir, "/...") { subDirs = true @@ -535,7 +544,7 @@ func runRuntimeSubTest(goroot string, args []string, tests []string, names []str } if hasHook { - err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(append(extraArgs, []string{"-run", "TestPreCheck"}...), nil), []string{"./hook_test.go"}) + err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(append(extraArgs, []string{"-run", "TestPreCheck"}...), nil), []string{"./hook_test.go"}, env) if err != nil { return err } @@ -550,20 +559,20 @@ func runRuntimeSubTest(goroot string, args []string, tests []string, names []str if runtime.GOOS == "windows" && tt.windowsFlags != nil { testFlags = tt.windowsFlags } - err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(extraArgs, testFlags), []string{testArgDir}) + err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(extraArgs, testFlags), []string{testArgDir}, env) if err != nil { return err } if hasHook { - err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(append(extraArgs, []string{"-run", "TestPostCheck"}...), nil), []string{"./hook_test.go"}) + err := doRunTest(goroot, testKind_xgoAny, tt.usePlainGo, runDir, amendArgs(append(extraArgs, []string{"-run", "TestPostCheck"}...), nil), []string{"./hook_test.go"}, env) if err != nil { return err } } } if len(names) == 0 { - err := doRunTest(goroot, testKind_runtimeSubTest, false, "", args, tests) + err := doRunTest(goroot, testKind_runtimeSubTest, false, "", args, tests, nil) if err != nil { return err } @@ -581,7 +590,7 @@ const ( testKind_xgoAny testKind = "xgo-any" ) -func doRunTest(goroot string, kind testKind, usePlainGo bool, dir string, args []string, tests []string) error { +func doRunTest(goroot string, kind testKind, usePlainGo bool, dir string, args []string, tests []string, env []string) error { goroot, err := filepath.Abs(goroot) if err != nil { return err @@ -685,6 +694,7 @@ func doRunTest(goroot string, kind testKind, usePlainGo bool, dir string, args [ execCmd.Env = os.Environ() execCmd.Env = append(execCmd.Env, "GOROOT="+goroot) execCmd.Env = append(execCmd.Env, "PATH="+filepath.Join(goroot, "bin")+string(filepath.ListSeparator)+os.Getenv("PATH")) + execCmd.Env = append(execCmd.Env, env...) return execCmd.Run() }