因此,该组中有很多内容建议您可以在Go中执行此操作(尽管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,正确的语法is实际上是省略-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

值得注意的是,try 这样链接(使用-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

也就是说.我绝对不是漏掉了a-l或-L.

推荐答案

事实证明,我的代码100%正常;它是GO 1.0的副本;在GO 1.1下,它可以正常工作. 在Go 1.0下,它不会.

(我知道回答我自己的问题有点蹩脚;但是下面的"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

另见:

Go相关问答推荐

如何模拟嵌入. FS?

CGO Linux到Windows交叉编译中的未知类型名称

为什么我不能使用Docker从本地访问我的Gin应用程序?

是不是有什么原因导致`Strings.EqualFold`不先进行长度比较?

埃拉托塞尼筛:加快交叉关闭倍数步骤

如何使用 go 读取 RDF xml 文件中的 XML 命名空间属性

如何使用 AWS sdk 在 Go 中正确解组 PartiQL 查询的结果?

运行 Docker 容器 - X11 无法打开显示:0

如何将任何类型的数据值传递到 Golang 中的 GRPC Protobuf struct ?

Go 中的 YAML 自定义标签

xml.Unmarshal 不支持的类型 struct

自定义 Fyne 自适应网格布局

动态 SQL 集 Golang

使用 os/exec 和在命令行执行之间的结果莫名其妙地不同

确保 Go 1.20 编译时的严格可比性?

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

从 Makefile 运行时权限被拒绝

Golang SSH客户端错误无法验证,try 的方法[无公钥],没有支持的方法

如何排除溢出矩阵的坐标

如何在眼镜蛇(golang)中将标志作为参数传递?