2

After reading articles I tried this:

env GOOS=linux GOARCH=amd64 go build -buildmode=c-shared -o hello.so testlib.go

It gave an error:

go: no Go source files

Then I enabled CGO by doing this:

env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -buildmode=c-shared -o hello.so testlib.go

and it gave a set of errors:

env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -buildmode=c-shared -o hello.so testlib.go
# runtime/cgo
linux_syscall.c:67:13: error: implicit declaration of function 'setresgid' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
linux_syscall.c:67:13: note: did you mean 'setregid'?
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:593:6: note: 'setregid' declared here
linux_syscall.c:73:13: error: implicit declaration of function 'setresuid' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
linux_syscall.c:73:13: note: did you mean 'setreuid'?
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:595:6: note: 'setreuid' declared here

Below are the versions:

Go: go version go1.19.4 darwin/amd64

GCC:

=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

1 Answer 1

2

Go's porting policy mentions:

All Linux first class ports are for systems using glibc only. Linux systems using other C libraries are not fully supported and are not treated as first class.

This then excludes cross-compiler solutions based on the glibc alternative musl for building GO shared libraries.

If you try it anyway (as in the first version of the answer, see edit history), it looks good at first sight when you check it with the file and nm command. But if you try to use the .so lib with a C program, there is the following crash:

error relocating ./libhello.so: free: initial-exec TLS resolves to dynamic definition in ./libhello.so

More info here: https://github.com/golang/go/issues/54805.

You then need a gcc based cross compiler - clang on macOS cannot be used for this. The easiest way to do this is to use Docker with an appropriate image, it reduces the effort to a single command line:

docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.19 env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -buildmode=c-shared -o libhello.so testlib.go

see https://index.docker.io/_/golang

One minor adjustment was to change the -o hello.so in your question to -o libhello.so to simply test with -lhello using gcc on a libc-based Linux.

By the way, this can then be done in this way:

cd testdir
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`
gcc -Wall -Wextra -L. test.c -lhello -o test
./test

Or if you don't want to bind the .so file statically at compile time / load it dynamically at runtime as shown above, but only want to load and bind the Go function symbols directly dynamically at runtime, the test would look even simpler:

gcc -Wall -Wextra test2.c -o test2
./test2
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.