I'm trying to use an external C library with my Go program.
I have tried the following:
package cgoexample
/*
#include <stdio.h>
#include <stdlib.h>
#cgo CFLAGS: -I/Users/me/somelib/include
#cgo LDFLAGS: /Users/me/somelib/libhello.a
#include "stinger.h"
void myprint(char* s) {
printf("%s", s);
}
*/
import "C"
import "unsafe"
//... more here
In the /Users/me/somelib/include
there is the .h file and in libhello.a
there is the .o file (I checked using the ar
command) that has the defined functions that are in the .h file.
It seems that the .h files are being linked OK, but it doesn't look like the archive file is being linked. I keep getting these:
warning: 'some_method_in_my_h_file" declared 'static' but never defined
And these warnings are being treated as errors. Regardless, they should be implemented in the archive file, so I'm confused what I'm doing wrong here.
When I run go build
and gun run
.
I have a feeling my #cgo
command is invalid (I'm not C expert),
Right, it doesn't work with ar object archives (*.a
). There are two things you can do:
Link it in as a shared library (-lfoo
in LDFLAGS
, with libfoo.so
in the library search path)
Put the *.c
files themselves within the Go package directory, so that go build
builds and links them in
If you're willing to go out of the standard go build
behavior, though, you can unpack the *.a
file into the individual object files, and then mimic the behavior of go build
and cgo
by hand.
For example, if you build a trivial cgo sample package with the -x
option, you should see output similar to this:
% go build -x
(...)
.../cgo (...) sample.go
(...)
gcc -I . -g (...) -o $WORK/.../_obj/sample.o -c ./sample.c
(...)
gcc -I . -g (...) -o $WORK/.../_obj/_all.o (...) $WORK/.../_obj/sample.o
(...)
.../pack grcP $WORK $WORK/.../sample.a (...) .../_obj/_all.o
cd .
.../6l -o $WORK/.../a.out (...) $WORK/.../sample.a
(...)
So you can see that the individual *.c
files are being compiled by gcc
, packed together into a Go-specific ar
archive, and then linked by 6l
. You can do these steps by hand as well, if for some reason you really cannot put the *.c
files in the package directory and let go build
handle them for you (which would be a lot simpler and give people the chance of go get
ing your package).