当使用`go build`编译cgo包时,找不到C标准库。

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

go build doesn't find my C standard library when compiling cgo package

问题

我正在尝试在树莓派上编译一个Go项目。

该项目有5个文件,两个小的.c文件和对应的.h文件(其中一个文件是我的代码,调用另一个文件,它是一个base64库),还有一个.go文件,使用cgo调用我的.c代码。

当我只使用gcc在树莓派上编译我的C代码(包括调用等)时,没有任何配置,它可以正常工作。

当我在我的x86 Linux Ubuntu机器上使用go build编译整个Go项目时,也可以正常工作。

但是当我尝试在树莓派上使用go build编译Go项目时,它无法找到我的C库:

fiatjaf@raspberrypi ~/g/s/b/f/project> go build -x
WORK=/tmp/go-build702187084
mkdir -p $WORK/bitbucket.org/fiatjaf/project/_obj/
cd /home/fiatjaf/go/src/bitbucket.org/fiatjaf/project
/usr/lib/go/pkg/tool/linux_arm/5c -FVw -I $WORK/bitbucket.org/fiatjaf/project/_obj/ -I /usr/lib/go/pkg/linux_arm -o $WORK/bitbucket.org/fiatjaf/project/_obj/base64.5 -DGOOS_linux -DGOARCH_arm ./base64.c
# bitbucket.org/fiatjaf/project
./base64.c:2 5c: No such file or directory: math.h

(如果我将<stdlib.h>放在<math.h>之前,问题也会出现在它上面,所以问题不是缺少math.h,我想)

我尝试过:

  • .go文件中添加// #cgo CFLAGS: -I/usr/include
  • 添加// #cgo LDFLAGS: -I/usr/include(我无法弄清楚这些标志的正确用法)
  • 使用go build -ldflags '-I/usr/include'

我不明白为什么Go尝试使用-I /usr/lib/go/pkg/linux_arm来编译base64.c。真的不明白。有人可以帮忙吗?

编辑:关于项目结构的澄清说明:

它有5个文件,2个C文件(以及对应的H文件):

base64.c

#include <math.h>
#include <stdint.h>
#include <stdlib.h>
... // 项目.c中使用的函数的定义

project.c

#include <stdlib.h>
#include <string.h>
#include "base64.h"
... // 项目.go中使用的函数

还有1个Go文件:

...

// #include <stdlib.h>
// #include <string.h>
// #include "project.h"
// #cgo CFLAGS: -I/usr/include
// #cgo LDFLAGS: -lm
import "C"
...

在这些声明中,我应该在哪里进行修改,以使其正常工作?为什么它在我的x86 Linux上可以工作?

英文:

I'm trying to compile a go project in a raspberry pi.

The project has 5 files, two small .c files and its counterparts .h (one of these files is my code -- it calls the other, which is a base64 library) and a .go files which calls my .c code using cgo.

When I compile my C code only (with its calls and everything) with gcc alone at the raspberry pi it does well without any configuration.

When I compile the entire go project on my x86 Linux Ubuntu machine with go build, it also does pretty well.

But when I try to compile the go project with go build in the raspberry pi it doesn't get my C libraries:

fiatjaf@raspberrypi ~/g/s/b/f/project&gt; go build -x
WORK=/tmp/go-build702187084
mkdir -p $WORK/bitbucket.org/fiatjaf/project/_obj/
cd /home/fiatjaf/go/src/bitbucket.org/fiatjaf/project
/usr/lib/go/pkg/tool/linux_arm/5c -FVw -I $WORK/bitbucket.org/fiatjaf/project/_obj/ -I /usr/lib/go/pkg/linux_arm -o $WORK/bitbucket.org/fiatjaf/project/_obj/base64.5 -DGOOS_linux -DGOARCH_arm ./base64.c
# bitbucket.org/fiatjaf/project
./base64.c:2 5c: No such file or directory: math.h

(If I put the &lt;stdlib.h&gt; before the &lt;math.h&gt; the problem occurs for it too, so the problem is not the absence of math.h, I think)
I tried to:

  • add // #cgo CFLAGS: -I/usr/include to the .go file
  • add // #cgo LDFLAGS: -I/usr/include (I can't discover what is the proper usage of these flags)
  • use go build -ldflags &#39;-I/usr/include&#39;

I don't understand why go is trying to compile base64.c with -I /usr/lib/go/pkg/linux_arm. Really don't. Someone help.

EDIT: Clarifying note about the structure of the project:

It has 5 files, 2 C (and its counterparts H):

base64.c

#include &lt;math.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;
... // definitions of functions used at project.c

project.c

#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &quot;base64.h&quot;
... // functions used at project.go

and 1 Go:

...

// #include &lt;stdlib.h&gt;
// #include &lt;string.h&gt;
// #include &quot;project.h&quot;
// #cgo CFLAGS: -I/usr/include
// #cgo LDFLAGS: -lm
import &quot;C&quot;
...

Where, what and how should I change in this declarations for this thing to work? And why did it worked on my x86 linux?

答案1

得分: 3

cgo内联语法

在Go文件中,cgo参数的正确语法是这样的:

// #cgo CFLAGS: -I/usr/include

#cgo之间没有空格。有关语法的详细信息,请参阅cmd/cgo

-ldflags参数

Go的-ldflags参数将参数传递给Go链接器(5l、6l、8l等)。即使参数将传递给C链接器,这对你也没有任何好处,因为链接器不处理包含文件,而是由编译器处理。

恐怕这个参数对你没有帮助。所有相关的参数应该在Go源文件中使用#cgo标签进行配置。

其他注意事项

如果你使用math.h,你很可能需要链接libmath。你可以在Go源文件中写入以下内容来实现:

// #cgo LDFLAGS: -lm
英文:

cgo inline syntax

The correct syntax for cgo parameters in the go file is this:

// #cgo CFLAGS: -I/usr/include

without the whitespace between # and cgo. See cmd/cgo for details on the syntax.

-ldflags parameter

The go -ldflags parameter passes parameters to the go linkers (5l, 6l, 8l, ...).
Even if the parameter would be passed to the C linker, this wouldn't do you any good
as the linker does not handle includes, the compiler does.

I'm afraid that this parameter won't help you here. All relevant parameters should
be configured in the go source file using the #cgo tags.

misc. notes

If you're using math.h you most likely need to link libmath. You can do this
by writing this to your go source file:

// #cgo LDFLAGS: -lm

答案2

得分: 1

似乎我的问题与未设置CGO_ENABLED标志有关。

我不确定,但是似乎是因为我从Raspbian存储库中卸载了Go(默认情况下似乎禁用了CGO),然后从源代码安装了Go(就像我在x86 Linux上做的那样),然后它开始工作了。

英文:

It seems my problem was something related to not having set the CGO_ENABLED flag.

I don't know for sure, but it seems, because I uninstalled my Go from the Raspbian repositories (which seems to come with CGO disabled by default) and installed Go from source (just like I had made in my x86 Linux) then it started to work.

huangapple
  • 本文由 发表于 2013年10月5日 07:32:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/19192293.html
匿名

发表评论

匿名网友

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

确定