[!cgo] skip 'this test requires cgo to be enabled' exec garble build ! stderr 'warning' # check that the C toolchain is happy exec ./main cmp stdout main.stdout ! binsubstr main$exe 'PortedField' 'test/main' [short] stop # no need to verify this with -short # Ensure that reversing works with cgo. env GARBLE_TEST_REVERSING=true exec ./main cp stdout reversing.stdout stdin reversing.stdout exec garble reverse . cmp stdout reversed.stdout env GARBLE_TEST_REVERSING=false exec garble -tiny build exec ./main cmp stdout main.stdout go build ! stderr 'warning' # check that the C toolchain is happy exec ./main cmp stdout main.stdout binsubstr main$exe 'privateAdd' -- go.mod -- module test/main go 1.22 -- main.go -- package main func main() { regularFunc() cgoFunc() } -- regular_main.go -- package main import ( "fmt" "os" "runtime" ) func regularFunc() { if os.Getenv("GARBLE_TEST_REVERSING") == "true" { _, filename, _, _ := runtime.Caller(0) fmt.Println("regular filename:", filename) } } -- cgo_main.go -- package main import ( "fmt" "os" "os/user" "runtime" ) /* #include "separate.h" // inline comment static int privateAdd(int a, int b) { return a + b; } extern void goCallback(); static void callGoCallback() { goCallback(); separateFunction(); } struct portedStruct { char* PortedField; }; */ import "C" func cgoFunc() { fmt.Println(C.privateAdd(C.int(1), C.int(2))) _, _ = user.Current() st := C.struct_portedStruct{} fmt.Println(st.PortedField == nil) C.callGoCallback() } //export goCallback func goCallback() { fmt.Println("go callback") // TODO: support reversing filenames in cgo files if false && os.Getenv("GARBLE_TEST_REVERSING") == "true" { _, filename, _, _ := runtime.Caller(0) fmt.Println("cgo filename:", filename) } } -- separate.h -- void separateFunction(); -- separate.c -- #include "_cgo_export.h" void separateFunction() { goCallback(); } -- main.stdout -- 3 true go callback go callback -- reversed.stdout -- regular filename: test/main/regular_main.go 3 true go callback go callback