Cgo include存档.a文件

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 geting your package).