github.com/gotranspile/cxgo@v0.3.7/compile_test.go (about) 1 package cxgo 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/gotranspile/cxgo/libs" 15 "github.com/gotranspile/cxgo/types" 16 ) 17 18 func gccCompile(t testing.TB, out, cfile string) { 19 var buf bytes.Buffer 20 cmd := exec.Command("gcc", "-O0", "-o", out, cfile) 21 cmd.Stdout = &buf 22 cmd.Stderr = &buf 23 err := cmd.Run() 24 if err != nil { 25 t.Fatalf("gcc compilation failed: %v\n%s", err, buf.String()) 26 } 27 } 28 29 func gccCompileAndExec(t testing.TB, dir, cfile string) progOut { 30 cbin := filepath.Join(dir, "out") 31 gccCompile(t, cbin, cfile) 32 return progExecute(dir, cbin) 33 } 34 35 func goCompile(t testing.TB, out, dir string) { 36 var buf bytes.Buffer 37 cmd := exec.Command("go", "build", "-o", out, ".") 38 cmd.Dir = dir 39 cmd.Stdout = &buf 40 cmd.Stderr = &buf 41 err := cmd.Run() 42 if err != nil { 43 t.Fatalf("go compilation failed: %v\n%s", err, buf.String()) 44 } 45 } 46 47 func goCompileAndExec(t testing.TB, dir string) progOut { 48 gobin := filepath.Join(dir, "out") 49 goCompile(t, gobin, dir) 50 return progExecute(dir, gobin) 51 } 52 53 func goTranspileAndExec(t testing.TB, cxgo, dir string, cfile string) progOut { 54 goProject(t, dir, cxgo) 55 gofile := filepath.Join(dir, "main.go") 56 env := libs.NewEnv(types.Config32()) 57 err := Translate(filepath.Dir(cfile), cfile, dir, env, Config{ 58 Package: "main", 59 GoFile: gofile, 60 MaxDecls: -1, 61 ForwardDecl: false, 62 }) 63 require.NoError(t, err) 64 goProjectMod(t, dir) 65 gosrc, err := ioutil.ReadFile(gofile) 66 require.NoError(t, err) 67 t.Logf("// === Go source ===\n%s", string(gosrc)) 68 return goCompileAndExec(t, dir) 69 } 70 71 type progOut struct { 72 Code int 73 Err error 74 Out string 75 } 76 77 func execInDir(wd string, bin string, args ...string) error { 78 cmd := exec.Command(bin, args...) 79 cmd.Dir = wd 80 return cmd.Run() 81 } 82 83 func progExecute(wd, bin string) progOut { 84 var buf bytes.Buffer 85 cmd := exec.Command(bin) 86 cmd.Dir = wd 87 cmd.Stdout = &buf 88 cmd.Stderr = &buf 89 err := cmd.Run() 90 out := progOut{ 91 Err: err, 92 Out: buf.String(), 93 } 94 if e, ok := err.(*exec.ExitError); ok && e.Exited() { 95 out.Code = e.ExitCode() 96 out.Err = nil 97 } 98 return out 99 } 100 101 func goProject(t testing.TB, out, cxgo string) { 102 cxgo, err := filepath.Abs(cxgo) 103 require.NoError(t, err) 104 105 err = os.MkdirAll(out, 0755) 106 require.NoError(t, err) 107 108 gomod := fmt.Sprintf(`module main 109 go 1.18 110 require ( 111 github.com/gotranspile/cxgo v0.0.0-local 112 ) 113 replace github.com/gotranspile/cxgo v0.0.0-local => %s`, cxgo) 114 115 err = ioutil.WriteFile(filepath.Join(out, "go.mod"), []byte(gomod), 0644) 116 require.NoError(t, err) 117 118 // allows running go mod tidy without having other source files and still keep require above 119 err = ioutil.WriteFile(filepath.Join(out, "dummy.go"), []byte(` 120 package main 121 122 import _ "github.com/gotranspile/cxgo/runtime/libc" 123 `), 0644) 124 require.NoError(t, err) 125 } 126 127 func goProjectMod(t testing.TB, out string) { 128 err := execInDir(out, "go", "mod", "tidy") 129 require.NoError(t, err) 130 }