[已解决]Golang静态库问题(CGO_ENABLED=0失效的解决方案)
[已解决]Golang静态库问题(CGO_ENABLED=0失效的解决方案) 大家好
首先,如果这是一个简单的配置问题或类似情况,我表示抱歉,我是一名初学者开发者。
我需要帮助,因为我无法使用静态库。 我编译了我的代码,并在另一台计算机上(显然没有安装Go)执行二进制文件,但我遇到了一个错误:“加载共享库时出错:libgo.so.14:无法打开共享对象文件:没有那个文件或目录” 因此,在谷歌上进行了一些搜索后,我发现需要将 CGO_ENABLED 环境变量更改为“0”以切换到静态库,但这对我无效。
我的 go env:
>> [jordan@jmaster] {11:52:47} ~$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jordan/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jordan/go"
GOPROXY=""
GORACE=""
GOROOT="/usr"
GOTMPDIR=""
GOTOOLDIR="/usr/libexec/gcc/x86_64-redhat-linux/9"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build185346707=/tmp/go-build -gno-record-gcc-switches -funwind-tables"
我的 go 版本:
>> [jordan@jmaster] {11:53:16} ~$ go version
go version go1.12.2 gccgo (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1) linux/amd64
当我编译我的代码时:
>> [jordan@jmaster] {11:56:23} /var/opt/development/golang/test$ ls
main.go
>> [jordan@jmaster] {11:56:24} /var/opt/development/golang/test$ go build -a -o app
>> [jordan@jmaster] {11:56:31} /var/opt/development/golang/test$ ldd app
linux-vdso.so.1 (0x00007ffdcfdca000)
libgo.so.14 => /lib64/libgo.so.14 (0x00007f599cef2000)
libm.so.6 => /lib64/libm.so.6 (0x00007f599cdac000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f599cd92000)
libc.so.6 => /lib64/libc.so.6 (0x00007f599cbcc000)
/lib64/ld-linux-x86-64.so.2 (0x00007f599e5f5000)
我期望的结果:
对 app 执行 ldd 返回“不是动态可执行文件”
感谢帮助。
更多关于[已解决]Golang静态库问题(CGO_ENABLED=0失效的解决方案)的实战教程也可以访问 https://www.itying.com/category-94-b0.html
经过无数次尝试,终于解决了……
Fedora 最新的 Go 版本是 1.12.2。 我刚刚移除了那个 yum 版本,并安装了 Go 官网上的 tar.gz 最新版本 (v1.13.3)。 嗒哒…… 成功了…… 😄
>> [jordan@jmaster] {21:06:55} /var/opt/development/golang/save$ go version
go version go1.13.3 linux/amd64
>> [jordan@jmaster] {21:07:00} /var/opt/development/golang/save$ ls
main.go
>> [jordan@jmaster] {21:07:06} /var/opt/development/golang/save$ go build -a -o app
>> [jordan@jmaster] {21:07:18} /var/opt/development/golang/save$ ldd app
not a dynamic executable
更多关于[已解决]Golang静态库问题(CGO_ENABLED=0失效的解决方案)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据你的描述,问题在于你使用的是 gccgo 编译器,而不是标准的 Go 编译器。gccgo 默认会生成动态链接的二进制文件,即使设置了 CGO_ENABLED=0。要生成完全静态的二进制文件,你需要使用标准的 Go 编译器(gc)或者为 gccgo 指定额外的链接选项。
解决方案
方案一:使用标准 Go 编译器(推荐)
首先,确保你安装的是标准的 Go 编译器,而不是 gccgo。你可以从 Go 官网 下载并安装。安装后,使用 go version 确认输出不包含 gccgo。
$ go version
go version go1.12.2 linux/amd64 # 标准编译器
然后,设置 CGO_ENABLED=0 并重新编译:
$ CGO_ENABLED=0 go build -a -o app main.go
$ ldd app
不是动态可执行文件 # 期望的输出
方案二:使用 gccgo 并指定静态链接
如果你必须使用 gccgo,可以通过传递 -static 标志给链接器来生成静态二进制文件:
$ go build -gccgoflags '-static' -o app main.go
$ ldd app
不是动态可执行文件
或者,你也可以在编译时直接使用 gccgo 命令:
$ gccgo -static -o app main.go
$ ldd app
不是动态可执行文件
示例代码
假设你的 main.go 内容如下:
package main
import "fmt"
func main() {
fmt.Println("Hello, static binary!")
}
使用标准 Go 编译器编译:
CGO_ENABLED=0 go build -a -o app main.go
使用 gccgo 编译:
go build -gccgoflags '-static' -o app main.go
验证
编译后,使用 file 命令验证二进制文件是否为静态链接:
$ file app
app: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=..., not stripped
使用 ldd 命令确认没有动态依赖:
$ ldd app
不是动态可执行文件
这样,你就可以在没有安装 Go 或其他依赖的机器上运行这个二进制文件了。

