当前位置: 首页 > 面试题库 >

如何使用cgo静态链接go中的ac库?

孙胜泫
2023-03-14
问题内容

因此,该小组中有很多建议您可以随时进行的工作(尽管不在cgo文档中):

package bridge

import "fmt"

// #cgo CFLAGS: -I/Users/doug/projects/c/go-bridge/include
// #cgo LDFLAGS: /Users/doug/projects/c/go-bridge/build/libgb.a
// #include <junk.h>
import "C"

func Run() {
  fmt.Printf("Invoking c library...\n")
  C.x(10)
  fmt.Printf("Done\n")
}

但是,它似乎不起作用:

/var/folders/.../bridge.a(bridge.cgo2.o)(__TEXT/__text): x: not defined

使用动态库,并检查生成的文件,这似乎可以很好地工作,它实际上在其中带有符号“ x”:

/var/folders/rg/hj4s3qlj3sz1d1b5p50ws0vc0000gn/T/go-build442792776/bridge/_obj/_cgo_.o:
0000000100001048 S _NXArgc 
0000000100001050 S _NXArgv 
0000000100001060 S ___progname 
0000000100000dc0 T __cgo_2d7eefe3d6d4_Cfunc_x
0000000100000da0 T __cgo_allocate 
0000000100000db0 T __cgo_panic
0000000100000000 T __mh_execute_header 
0000000100000d90 T _crosscall2
0000000100001058 S _environ
                 U _exit 
0000000100000d80 T _main
                 U _puts 
0000000100001000 s _pvars 
0000000100000de0 T _x                <------- Exists
                 U dyld_stub_binder 
0000000100000d40 T start

但显然只是bridge.cgo2.o中的标记:

/var/folders/rg/hj4s3qlj3sz1d1b5p50ws0vc0000gn/T/go-build442792776/bridge.a(bridge.cgo2.o):
0000000000000368 s EH_frame0
0000000000000000 T __cgo_2d7eefe3d6d4_Cfunc_x
0000000000000380 S __cgo_2d7eefe3d6d4_Cfunc_x.eh
                 U _x

我究竟做错了什么?

对于ref,c标头:

int x(int y);

和代码:

#include <junk.h>
#include <stdio.h>

int x(int y) {
  printf("Hello World\n");
  return y;
}

--

编辑:

不,-L和-l也不起作用;实际上,在Google网上论坛上有一些具体讨论,认为该(-l / blah / blah.a)对cgo不起作用,实际上正确的语法
省略-l并仅列出.a文件…但是嘿,如果可以的话,我完全会用它。但事实并非如此:

dougs-mini:go doug$ go run test.go
# bridge
ld: library not found for -l/Users/doug/projects/c/go-bridge/build/libgb.a
collect2: ld returned 1 exit status
dougs-mini:go doug$ ls -l /Users/doug/projects/c/go-bridge/build/libgb.a
-rw-r--r--  1 doug  staff  872 25 May 14:02 /Users/doug/projects/c/go-bridge/build/libgb.a

详细版本:

dougs-mini:go doug$ go build -work -x test.go
WORK=/var/folders/rg/hj4s3qlj3sz1d1b5p50ws0vc0000gn/T/go-build354497708
mkdir -p $WORK/bridge/_obj/
cd /Users/doug/projects/c/go-bridge/go/src/bridge
/Users/doug/projects/go/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/bridge/_obj/ -- -I/Users/doug/projects/c/go-bridge/include -I $WORK/bridge/_obj/ bridge.go
/Users/doug/projects/go/go/pkg/tool/darwin_amd64/6c -FVw -I $WORK/bridge/_obj/ -I /Users/doug/projects/go/go/pkg/darwin_amd64 -o $WORK/bridge/_obj/_cgo_defun.6 -DGOOS_darwin -DGOARCH_amd64 $WORK/bridge/_obj/_cgo_defun.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I/Users/doug/projects/c/go-bridge/include -I $WORK/bridge/_obj/ -o $WORK/bridge/_obj/_cgo_main.o -c $WORK/bridge/_obj/_cgo_main.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I/Users/doug/projects/c/go-bridge/include -I $WORK/bridge/_obj/ -o $WORK/bridge/_obj/_cgo_export.o -c $WORK/bridge/_obj/_cgo_export.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I/Users/doug/projects/c/go-bridge/include -I $WORK/bridge/_obj/ -o $WORK/bridge/_obj/bridge.cgo2.o -c $WORK/bridge/_obj/bridge.cgo2.c
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o $WORK/bridge/_obj/_cgo_.o $WORK/bridge/_obj/_cgo_main.o $WORK/bridge/_obj/_cgo_export.o $WORK/bridge/_obj/bridge.cgo2.o -l/Users/doug/projects/c/go-bridge/build/libgb.a
# bridge
ld: library not found for -l/Users/doug/projects/c/go-bridge/build/libgb.a
collect2: ld returned 1 exit status

值得注意的是,尝试像这样链接(使用-l)时失败是gcc链接失败的典型原因,因为您尝试合并一组目标文件。

即。这个:

gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o ... -l/path/libgb.a

永远不会在gcc下编译;您 必须 像这样链接静态库:

gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o ... /path/libgb.a

即。绝对不是我缺少-l或-L。


问题答案:

原来我的代码是100%罚款;它是Go 1.0的副本;在go 1.1下可以正常工作。在go 1.0下,它不是。

(我知道回答我自己的问题有点la脚;但是下面的’use -L -l答案也不对;与之无关)。

GitHub上有一个可行的解决方案示例,适用于以后发现此问题的任何人:

https://github.com/shadowmint/go-static-
linking

简而言之:

CGO_ENABLED=0 go build -a -installsuffix cgo -ldflags '-s' src/myapp/myapp.go

另请参阅:https :
//github.com/golang/go/issues/9344



 类似资料:
  • 问题内容: 我有一个Go库,它为C ++ OpenImageIO库(OpenImageiGO)提供绑定。我一直在通过与libOpenImageIO的标准动态链接来构建绑定,但现在尝试静态链接。我遇到了一个问题,无论我尝试使用哪种标志组合,外部链接器都会失败,并出现大量“未定义的引用”错误。我似乎回想起过去曾提到过的这个问题,他说链接器看到符号的顺序存在问题。但我似乎再也找不到此信息。 这是我最近一

  • 主要内容:静态链接库,动态链接库,总结我们知道,C、C++程序从源文件到生成可执行文件需经历 4 个阶段,分别为预处理、编译、汇编和链接,本节将重点围绕链接阶段,对静态链接库和动态链接库做详细的讲解。 有关链接操作的具体细节,感兴趣的读者可阅读《 到底什么是链接,它起到了什么作用?》和《 符号——链接的粘合剂》这两节。总的来说链接阶段要完成的工作,就是将同一项目中各源文件生成的目标文件以及程序中用到的库文件整合为一个可执行文件。 通过

  • 问题内容: 我想编译NRPE,因此可以将编译后的二进制文件复制到不希望安装gcc的OmniOS服务器上。我希望从存储库中安装具有SSl支持的NRPE,但是这种接缝不存在,所以我想自己编译它。但是,脚本不包含它所接缝的静态选项 题 如何编译静态使用的程序? 问题答案: 尝试这个:

  • 问题内容: 我想使用以下c作为Go的cgo: 建立: 我为Go的cgo重新编写了该代码: 尝试编译为: 但是我收到链接器错误: /tmp/go- build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o:在函数XScreenSaverAllocInfo中/tmp/go- build076004816/opensource.stdk/lib/t

  • 静态链接方法:静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来 静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库 动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这

  • 在编译Linux程序时,我们经常会看到动态链接和静态链接这两个术语。这两个术语中是我Linux的共享函数库(shared libraries)相关的。共享函数库就象Windows系统里的.dll文件,它里面包含有很多程序常用的函数。为了方便程序开发和减少程序的冗余,程序当中就不用包含每个常用函数的拷贝,只是在需要时调用系统中共享函数库中常函数功能即可。这种方式我们称之为动态链接(Dynamical