英文:
Cgo include archive .a file
问题
我正在尝试在我的Go程序中使用一个外部的C库。
我尝试了以下代码:
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
在/Users/me/somelib/include
目录下有一个.h文件,在libhello.a
中有一个.o文件(我使用ar
命令进行了检查),其中定义了.h文件中的函数。
似乎.h文件已经被正确链接,但似乎没有链接到存档文件。我一直收到以下警告:
warning: 'some_method_in_my_h_file' declared 'static' but never defined
这些警告被视为错误处理。无论如何,它们应该在存档文件中实现,所以我对我在这里做错了什么感到困惑。
当我运行go build
和go run
时。
我有一种感觉我的#cgo
命令是无效的(我不是C专家),
英文:
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),
答案1
得分: 3
没问题,以下是翻译好的内容:
没错,它不支持ar对象归档文件(*.a
)。你可以采取两种方法:
-
将其作为共享库链接(在
LDFLAGS
中使用-lfoo
,并将libfoo.so
放在库搜索路径中) -
将
*.c
文件本身放在Go包目录中,这样go build
会构建并链接它们
不过,如果你愿意违背标准的go build
行为,你也可以手动解压*.a
文件为单独的目标文件,然后模仿go build
和cgo
的行为。
例如,如果你使用-x
选项构建一个简单的cgo示例包,你应该会看到类似于以下的输出:
% 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
(...)
所以你可以看到,单独的*.c
文件被gcc
编译,打包到一个特定于Go的ar
归档文件中,然后由6l
进行链接。如果由于某种原因你真的不能将*.c
文件放在包目录中并让go build
来处理它们(这样会更简单,并且让人们有机会go get
你的包),你也可以手动执行这些步骤。
英文:
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
inLDFLAGS
, withlibfoo.so
in the library search path) -
Put the
*.c
files themselves within the Go package directory, so thatgo 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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论