使用C库编译Go程序为独立可执行文件

4

我正在尝试编译一个Go程序,使其完全独立,包括C库。我使用的命令是

[mm17@mm17 grogger]$ go build --ldflags '-extldflags "-static"' ./grogger.go
# command-line-arguments
/usr/bin/ld: cannot find -lgrok
collect2: ld returned 1 exit status
/home/mm17/go/pkg/tool/linux_amd64/6l: running gcc failed: unsuccessful exit status 0x100

因此,我将修改调用grok库的文件以包含以下标题

  1 package grok
  2
  3 /*
  4 #cgo LDFLAGS: -L /usr/lib/libgrok.so -lgrok
  5 #include <grok.h>
  6 */
  7 import "C"

然后运行相同的命令会得到以下结果:

[mm17@mm17 grogger]$ go build --ldflags '-extldflags "-static"' ./grogger.go
# github.com/blakesmith/go-grok
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400180
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_strlen':
../../blakesmith/go-grok/grok.go:169: undefined reference to `strlen'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_patterns_import_from_file':
../../blakesmith/go-grok/grok.go:159: undefined reference to `grok_patterns_import_from_file'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_pattern_add':
../../blakesmith/go-grok/grok.go:147: undefined reference to `grok_pattern_add'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_new':
../../blakesmith/go-grok/grok.go:132: undefined reference to `grok_new'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_match_walk_next':
../../blakesmith/go-grok/grok.go:123: undefined reference to `grok_match_walk_next'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_exec':
../../blakesmith/go-grok/grok.go:81: undefined reference to `grok_exec'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_discover_new':
../../blakesmith/go-grok/grok.go:68: undefined reference to `grok_discover_new'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_compile':
../../blakesmith/go-grok/grok.go:46: undefined reference to `grok_compile'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_match_walk_init':
../../blakesmith/go-grok/grok.go:108: undefined reference to `grok_match_walk_init'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_match_walk_end':
../../blakesmith/go-grok/grok.go:99: undefined reference to `grok_match_walk_end'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_free':
../../blakesmith/go-grok/grok.go:90: undefined reference to `grok_free'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_grok_discover':
../../blakesmith/go-grok/grok.go:58: undefined reference to `grok_discover'
/tmp/go-build731085030/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_free':
../../blakesmith/go-grok/grok.go:34: undefined reference to `free'
collect2: ld returned 1 exit status

如果我尝试正常构建它,也会得到同样的结果:

[mm17@mm17 grogger]$ go build grogger.go
# github.com/blakesmith/go-grok
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400180
/tmp/go-build294631148/github.com/blakesmith/go-grok/_obj/grok.cgo2.o: In function `_cgo_4244208c3352_Cfunc_strlen':
../../blakesmith/go-grok/grok.go:169: undefined reference to `strlen'
....

我相信我只是做了一些愚蠢的事情,但我似乎无法弄清楚,当涉及到gcc和go时,我就是一个很新手的人,这是我第一个非玩具程序。


-lc添加到LDFLAGS是否有帮助? #cgo LDFLAGS:-L /usr/lib/libgrok.so -lgrok -lc - OneOfOne
还是一样的结果。 - GardenMWM
1
你的库路径中是否有libgrok.a?从共享库无法生成静态可执行文件。 - JimB
不,我想我需要将所有库静态编译。 - GardenMWM
1
另外,-L 参数的参数应该是包含库文件的目录,而不是单个库文件的文件名。(如果您没有静态库文件可用,则可能无济于事) - James Henstridge
1个回答

0

当您使用GCC编译本地库时,请确保使用-fPIC选项。

如果库没有使用-fPIC进行编译,则GO将无法在其中定位函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接