包含归档文件 .a 的代码部分。

huangapple go评论81阅读模式
英文:

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 buildgo run时。

我有一种感觉我的#cgo命令是无效的(我不是C专家),

英文:

I'm trying to use an external C library with my Go program.

I have tried the following:

package cgoexample

/*
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#cgo CFLAGS: -I/Users/me/somelib/include 
#cgo LDFLAGS: /Users/me/somelib/libhello.a
#include &quot;stinger.h&quot;
void myprint(char* s) {
        printf(&quot;%s&quot;, s);
}
*/
import &quot;C&quot;

import &quot;unsafe&quot;
//... 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: &#39;some_method_in_my_h_file&quot; declared &#39;static&#39; 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 buildcgo的行为。

例如,如果你使用-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 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).

huangapple
  • 本文由 发表于 2013年9月6日 01:38:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/18642613.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定