diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0ba03923..bc80f96e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: test: strategy: matrix: - os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest] + os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest, windows-11-arm] go: ['1.25.x', '1.26.x'] name: Test with Go ${{ matrix.go }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -31,8 +31,8 @@ jobs: with: go-version: ${{ matrix.go }} - - name: Set up the prerequisites - if: runner.os == 'Windows' + - name: Set up Msys2 + if: runner.os == 'Windows' && runner.arch != 'ARM64' uses: msys2/setup-msys2@v2 - name: go vet @@ -127,6 +127,10 @@ jobs: if: runner.os == 'Windows' run: | env CGO_ENABLED=0 GOARCH=386 go test -shuffle=on -v -count=10 ./... + + - name: go test (Windows 386, Cgo) + if: runner.os == 'Windows' && runner.arch != 'ARM64' + run: | env CGO_ENABLED=1 GOARCH=386 go test -shuffle=on -v -count=10 ./... - name: go test (Linux 386) @@ -180,6 +184,7 @@ jobs: env CGO_ENABLED=0 go test -race -shuffle=on -v -count=10 ./... - name: go test race (Cgo) + if: ${{ !(runner.os == 'Windows' && runner.arch == 'ARM64') }} run: | env CGO_ENABLED=1 go test -race -shuffle=on -v -count=10 ./... diff --git a/callback_test.go b/callback_test.go index b298081b..ec795990 100644 --- a/callback_test.go +++ b/callback_test.go @@ -22,7 +22,7 @@ func TestCallGoFromSharedLib(t *testing.T) { libFileName := filepath.Join(t.TempDir(), "libcbtest.so") t.Logf("Build %v", libFileName) - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -186,7 +186,7 @@ func TestCallbackInt32Packing(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -218,7 +218,7 @@ func TestCallbackMixedStackPacking(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -251,7 +251,7 @@ func TestCallbackSmallTypesPacking(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -319,7 +319,7 @@ func TestCallback10Int32Packing(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -350,7 +350,7 @@ func TestCallbackFloat64StackPacking(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -384,7 +384,7 @@ func TestCallbackFloat32StackPacking(t *testing.T) { } libFileName := filepath.Join(t.TempDir(), "libcbtest_packing.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_packing_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) diff --git a/dlfcn_test.go b/dlfcn_test.go index 7ca5456c..e358b9bd 100644 --- a/dlfcn_test.go +++ b/dlfcn_test.go @@ -24,7 +24,7 @@ func TestNestedDlopenCall(t *testing.T) { libFileName := filepath.Join(t.TempDir(), "libdlnested.so") t.Logf("Build %v", libFileName) - if err := buildSharedLib("CXX", libFileName, filepath.Join("testdata", "libdlnested", "nested_test.cpp")); err != nil { + if err := buildSharedLib(t, "CXX", libFileName, filepath.Join("testdata", "libdlnested", "nested_test.cpp")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) diff --git a/func_test.go b/func_test.go index 85e80e82..970919bb 100644 --- a/func_test.go +++ b/func_test.go @@ -178,13 +178,10 @@ func TestRegisterLibFunc_Bool(t *testing.T) { } func TestABI(t *testing.T) { - if runtime.GOOS == "windows" && runtime.GOARCH == "386" { - t.Skip("need a 32bit gcc to run this test") // TODO: find 32bit gcc for test - } libFileName := filepath.Join(t.TempDir(), "abitest.so") t.Logf("Build %v", libFileName) - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { t.Fatal(err) } @@ -242,11 +239,8 @@ func TestABI(t *testing.T) { } func TestABI_ArgumentPassing(t *testing.T) { - if runtime.GOOS == "windows" && runtime.GOARCH == "386" { - t.Skip("need a 32bit gcc to run this test") // TODO: find 32bit gcc for test - } libFileName := filepath.Join(t.TempDir(), "abitest.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { t.Fatal(err) } lib, err := load.OpenLibrary(libFileName) @@ -603,7 +597,8 @@ func TestABI_TooManyArguments(t *testing.T) { }) } -func buildSharedLib(compilerEnv, libFile string, sources ...string) error { +func buildSharedLib(tb testing.TB, compilerEnv, libFile string, sources ...string) error { + tb.Helper() // When PUREGO_TEST_PREBUILT_LIBDIR is set, the shared library has been // cross-compiled ahead of time and placed in that directory under the // base name of libFile. This allows running the tests on a target that @@ -619,6 +614,18 @@ func buildSharedLib(compilerEnv, libFile string, sources ...string) error { return nil } + // Compiling the library needs a C toolchain targeting GOARCH. CI has none + // for Windows on 386 or arm64, so skip those (the prebuilt path above + // avoids the toolchain). + if runtime.GOOS == "windows" { + switch runtime.GOARCH { + case "386": + tb.Skip("need a 386 C toolchain to run this test") // TODO: find a 386 C toolchain for test + case "arm64": + tb.Skip("need an arm64 C toolchain to run this test") + } + } + out, err := exec.Command("go", "env", compilerEnv).Output() if err != nil { return fmt.Errorf("go env %s error: %w", compilerEnv, err) diff --git a/struct_test.go b/struct_test.go index a9cd6148..14ed0584 100644 --- a/struct_test.go +++ b/struct_test.go @@ -24,7 +24,7 @@ func TestRegisterFunc_structArgs(t *testing.T) { libFileName := filepath.Join(t.TempDir(), "structtest.so") t.Logf("Build %v", libFileName) - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "structtest", "struct_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "structtest", "struct_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) @@ -859,7 +859,7 @@ func TestRegisterFunc_structReturns(t *testing.T) { libFileName := filepath.Join(t.TempDir(), "structreturntest.so") t.Logf("Build %v", libFileName) - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "structtest", "structreturn_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "structtest", "structreturn_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName) diff --git a/syscall_bench_test.go b/syscall_bench_test.go index 86e8a0c7..4f835c12 100644 --- a/syscall_bench_test.go +++ b/syscall_bench_test.go @@ -37,7 +37,7 @@ func BenchmarkCallingMethods(b *testing.B) { // Build C library for benchmarking libFileName := filepath.Join(b.TempDir(), "libbenchmark.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "benchmarktest", "benchmark.c")); err != nil { + if err := buildSharedLib(b, "CC", libFileName, filepath.Join("testdata", "benchmarktest", "benchmark.c")); err != nil { b.Fatalf("Failed to build C library: %v", err) } b.Cleanup(func() { diff --git a/syscall_linux_test.go b/syscall_linux_test.go index 6a331e3a..45ce47e4 100644 --- a/syscall_linux_test.go +++ b/syscall_linux_test.go @@ -173,7 +173,7 @@ func compareStatus(filter, expect string) error { func TestDlopenThenAllThreadsSyscall(t *testing.T) { // Step 1: Build and load a shared C library that calls back into Go. libFileName := filepath.Join(t.TempDir(), "libcbtest.so") - if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil { + if err := buildSharedLib(t, "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil { t.Fatal(err) } defer os.Remove(libFileName)