Polyglot
Basic support for go to call C code without direct use of cgo (import "C"). Inspired by syscall, golang.org/x/sys, and github.com/ebitengine/purego.
Supported modes
| Operating System |
Architecture |
Mode |
Cross Compiling |
| Linux |
amd64/arm64 |
fully dynamic linking (.so) |
no |
| Linux |
amd64/arm64 |
statically link against a library (.o or .a), dynamically link against libc |
no |
| Darwin |
arm64 |
fully dynamic linking (.dylib) |
yes |
| Darwin |
arm64 |
statically link against a library (.o or .a), dynamically link against libc |
no |
| Windows |
TBD |
TBD |
TBD |
Building the examples
To build the examples, run:
$ ./build.sh
Fully dynamic linking
Dynamic linking on macOS is possible without cgo, such as when cross compiling. Still investigating if it's possible on Linux. For either operating system, the corresponding dynamic library must be distributed with the executable. See examples/dynamic.
$ ldd bin/dynamic_linux
linux-vdso.so.1 (0x00007f27cac30000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f27caa44000)
bin/libnative.so (0x00007f27caa3f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f27cac32000)
And the output when you run it:
$ bin/dynamic_linux
link with libnative
native_one(5)
true
false
native_six (examples/c/native.c:18)
true
Note that until Linux errno support is sorted out, false is printed for the fourth line.
Statically link against a library
Static linking against a library, but still dynamically linking against libc, requires cgo as it uses the the external linker (-ldflags '-linkmode external ...') but allows distributing a single file. See examples/link.
$ ldd bin/link
linux-vdso.so.1 (0x00007f72de469000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f72de27d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f72de46b000)
And the output when you run it:
$ bin/link
link with native.o
native_one(5)
true
false
native_six (examples/c/native.c:18)
true
Note that until Linux errno support is sorted out, false is printed for the fourth line.
Windows support
Support for Windows is provided by golang itself. It should be relatively easy to add support for it here as well.
Static executable
It is likely possible on Linux to statically link against a library and libc to create a fully static executable. This is left as an exercise for the reader.