Linux下交叉编译Solaris平台cgo代码遇链接错误求助
Linux交叉编译Solaris平台CGO代码的链接错误问题
问题描述
我在Linux环境下交叉编译Solaris平台的CGO代码时,执行以下编译命令出现链接错误:
CGO_LDFLAGS="-L$(pwd)/solaris-11.4-amd64-libs" CGO_CFLAGS='-I/home/shane/src/ioctl-experimentation/solaris-11.4-headers -Wno-unknown-pragmas' CGO_ENABLED=1 GOOS=solaris GOARCH=amd64 go build
错误输出:
# runtime/cgo /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x16): undefined reference to `__libc_csu_fini' /usr/bin/ld: (.text+0x1d): undefined reference to `__libc_csu_init' /usr/bin/ld: (.text+0x2a): undefined reference to `__libc_start_main' /usr/bin/ld: $WORK/b003/_x003.o: in function `_cgo_release_context': gcc_context.c:(.text+0x5c): undefined reference to `__stack_chk_fail' /usr/bin/ld: $WORK/b003/_x004.o: in function `x_cgo_sys_thread_create': gcc_libinit.c:(.text+0x87): undefined reference to `__stack_chk_fail' /usr/bin/ld: $WORK/b003/_x004.o: in function `_cgo_wait_runtime_init_done': gcc_libinit.c:(.text+0x121): undefined reference to `__stack_chk_fail' /usr/bin/ld: $WORK/b003/_x004.o: in function `_cgo_try_pthread_create': gcc_libinit.c:(.text+0x291): undefined reference to `__stack_chk_fail' /usr/bin/ld: $WORK/b003/_x006.o: in function `x_cgo_init': gcc_solaris_amd64.c:(.text+0xb6): undefined reference to `__stack_chk_fail' /usr/bin/ld: $WORK/b003/_x006.o:gcc_solaris_amd64.c:(.text+0x214): more undefined references to `__stack_chk_fail' follow collect2: error: ld returned 1 exit status
环境与文件说明
- 编译环境:Linux
- Go版本:
go version go1.18.3 linux/amd64
solaris-11.4-amd64-libs目录:包含从Solaris 11.4 AMD64机器复制的/lib/amd64下所有文件solaris-11.4-headers目录:包含该机器/usr/include下所有文件
代码示例(main.go)
//go:build solaris // +build solaris package main import "C" func main() { }
已尝试的解决方法
我知道Go 1.5起已完全支持Solaris平台的CGO,当前用的Go 1.18版本也符合要求。已经复制了/lib/amd64下的所有库,但还是报错。根据建议尝试了以下操作,均无效:
- 在
CGO_LDFLAGS中添加-Xlinker -rpath=$(pwd)/solaris-11.4-amd64-libs - 单独或组合使用
-nodefaultlibs和-nostdlib参数,反而导致更多链接错误
想知道错误原因,是否还需要复制其他库?
问题原因与解决思路
你遇到的核心问题是交叉编译时链接器错误地使用了Linux的libc相关文件,而非Solaris的库:
- 启动文件不匹配:错误里提到的
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o是Linux系统的启动目标文件,不是Solaris的。Go交叉编译CGO时默认调用本地gcc/ld,这些工具会优先使用Linux的系统库和启动代码,和你提供的Solaris库完全不兼容。 - 符号查找错误:
__stack_chk_fail等符号是Solaris libc的专属函数,但链接器一直在Linux的libc里查找,自然找不到匹配项。
解决步骤
1. 安装Solaris交叉编译工具链
必须使用针对Solaris的交叉编译gcc工具链(比如x86_64-pc-solaris2.11-gcc),不能用Linux本地的gcc。本地gcc生成的目标文件和启动代码都是面向Linux的,无法和Solaris库链接。
2. 指定交叉编译工具
通过CC环境变量指定Solaris交叉编译器,同时显式指定链接Solaris的libc:
CC=x86_64-pc-solaris2.11-gcc CGO_LDFLAGS="-L$(pwd)/solaris-11.4-amd64-libs -lc" CGO_CFLAGS='-I/home/shane/src/ioctl-experimentation/solaris-11.4-headers -Wno-unknown-pragmas' CGO_ENABLED=1 GOOS=solaris GOARCH=amd64 go build
3. 补充完整的Solaris库文件
除了/lib/amd64,还需要复制Solaris机器上/usr/lib/amd64目录下的核心库,比如libc.so.1、libpthread.so.1等,确保交叉编译器能找到所有依赖的符号。
4. 手动指定Solaris启动文件(备选方案)
如果无法获取完整交叉工具链,可以尝试禁用本地启动文件,手动指定从Solaris复制的启动目标文件(crt1.o、crti.o、crtn.o):
CGO_LDFLAGS="-L$(pwd)/solaris-11.4-amd64-libs -nostartfiles $(pwd)/solaris-11.4-amd64-libs/crt1.o $(pwd)/solaris-11.4-amd64-libs/crti.o $(pwd)/solaris-11.4-amd64-libs/crtn.o -lc" CGO_CFLAGS='-I/home/shane/src/ioctl-experimentation/solaris-11.4-headers -Wno-unknown-pragmas' CC=x86_64-pc-solaris2.11-gcc CGO_ENABLED=1 GOOS=solaris GOARCH=amd64 go build
关键注意点
- 单纯复制Solaris库文件没用,必须配合对应平台的交叉编译工具链,Linux的gcc/ld无法生成符合Solaris格式的可执行文件。
- Go的CGO交叉编译完全依赖目标平台的C工具链,一定要确保
CC指向Solaris交叉编译器,而非本地Linux编译器。
内容的提问来源于stack exchange,提问作者Shane Bishop
相关产品推荐
相关产品推荐

