Golang中CGO在Mac上如何链接整个库
Golang中CGO在Mac上如何链接整个库
我正在使用一个.a文件格式的库,该库需要在链接过程中被完整导入。
不幸的是,标志-Wl,-all_load在MacOS上不起作用,而标志-Wl,--whole-archive在Linux上不起作用:
#cgo darwin LDFLAGS: -L.. -Wl,-all_load -lmy_lib
go build _/Users/thierryfournier/git/my-lib/my_lib: invalid flag in #cgo LDFLAGS: -Wl,-all_load
在Linux上使用完整归档也不行:
#cgo LDFLAGS: -L.. -Wl,--whole-archive -lmy_lib
go build _/home/thierry/my_lib/my_lib: invalid flag in #cgo LDFLAGS: -Wl,--whole-archive
因此,我找不到任何方法来嵌入整个库。
- 我找不到理解链接器如何被调用的方法。
- 我找不到关于支持哪些标志的文档。
如果有人有解决方案或线索,将不胜感激。
谢谢。
更多关于Golang中CGO在Mac上如何链接整个库的实战教程也可以访问 https://www.itying.com/category-94-b0.html
“不起作用”具体是什么意思?你遇到错误了吗?
更多关于Golang中CGO在Mac上如何链接整个库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,帖子中的错误是:
go build _/home/thierry/my_lib/my_lib: invalid flag in #cgo LDFLAGS: -Wl,--whole-archive
采用Ian的建议,
https://groups.google.com/d/msg/golang-nuts/0ANTUXa59aU/yFTAHuRCBQAJ 将这些标志添加到CGO_LDFLAGS_ALLOW环境变量中。
出于安全原因,只允许使用有限的标志集,特别是-D、-U、-I和-l。要允许额外的标志,请将CGO_CFLAGS_ALLOW设置为匹配新标志的正则表达式。要禁止原本允许的标志,请将CGO_CFLAGS_DISALLOW设置为匹配必须禁止的参数的正则表达式。在这两种情况下,正则表达式必须匹配完整的参数:要允许-mfoo=bar,请使用CGO_CFLAGS_ALLOW=’-mfoo.*’,而不仅仅是CGO_CFLAGS_ALLOW=’-mfoo’。类似命名的变量控制允许的CPPFLAGS、CXXFLAGS、FFLAGS和LDFLAGS。
对于Linux,
#cgo linux LDFLAGS: -L.. -Wl,--whole-archive -lmy_lib -Wl,--no-whole-archive
CGO_LDFLAGS_ALLOW='-Wl,--(?:no-)?whole-archive' go build
在Golang的CGO中,MacOS和Linux平台确实需要使用不同的链接器标志来链接整个静态库。问题在于#cgo指令中不能直接使用-Wl,前缀的链接器标志,需要通过CGO_LDFLAGS环境变量或构建标签来设置。
以下是解决方案:
1. 使用环境变量设置(推荐)
对于MacOS:
export CGO_LDFLAGS="-L.. -Wl,-all_load -lmy_lib"
go build
对于Linux:
export CGO_LDFLAGS="-L.. -Wl,--whole-archive -lmy_lib -Wl,--no-whole-archive"
go build
2. 在Go文件中使用构建标签
创建两个文件,分别处理不同平台:
my_lib_darwin.go:
//go:build darwin
// +build darwin
package main
/*
#cgo darwin LDFLAGS: -L.. -lmy_lib
*/
import "C"
my_lib_linux.go:
//go:build linux
// +build linux
package main
/*
#cgo linux LDFLAGS: -L.. -lmy_lib
*/
import "C"
然后在构建时通过环境变量传递链接器标志:
# MacOS
CGO_LDFLAGS="-Wl,-all_load" go build
# Linux
CGO_LDFLAGS="-Wl,--whole-archive -Wl,--no-whole-archive" go build
3. 使用Makefile或构建脚本
创建Makefile:
UNAME := $(shell uname)
ifeq ($(UNAME), Darwin)
CGO_LDFLAGS = -Wl,-all_load
else
CGO_LDFLAGS = -Wl,--whole-archive -Wl,--no-whole-archive
endif
build:
CGO_LDFLAGS="$(CGO_LDFLAGS)" go build -o myapp
4. 直接指定库文件路径
如果.a文件路径明确,可以直接链接文件而不是使用-l选项:
/*
#cgo darwin LDFLAGS: ../libmy_lib.a -Wl,-all_load
#cgo linux LDFLAGS: ../libmy_lib.a -Wl,--whole-archive
*/
import "C"
调试链接器调用:
go build -x -work
这会显示详细的构建过程,包括链接器调用的完整命令。


