英文:
No longer able to build static linked binary with exact same `go build` command after some code change, but why?
问题
我已经在这个关于使用go build
进行静态链接的问题上纠结了几天了。
要重现问题,请按照以下步骤操作:
- 克隆仓库
$ git clone https://github.com/IceWhaleTech/CasaOS-UserService.git
$ cd CasaOS-UserService/
- 切换到静态链接出现问题的提交:
$ git checkout e2d9ecf2299dca7f65de094e552276286d7bb417
- 构建
$ CGO_ENABLED=1 go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo ./cmd/migration-tool # 使用静态链接参数构建代码
$ file migration-tool
migration-tool: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=6bRf1bPBESbFSmuueVEn/fIR_ucgSolvxHG8CoZsj/AAKVZda1Jflk5MBdCj74/Tv1-5IxySthe8moShu27, stripped
输出显示它是动态链接的。
- 切换到前一个提交并再次构建(使用完全相同的命令)
$ git checkout HEAD~1
$ CGO_ENABLED=1 go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo ./cmd/migration-tool
$ file migration-tool
migration-tool: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=bddccd9307afc326a4645279c9275b6087acc62a, for GNU/Linux 3.2.0, stripped
前一个提交的构建是静态链接的!
可以在这里找到两个提交之间的差异:
https://github.com/IceWhaleTech/CasaOS-UserService/commit/e2d9ecf2299dca7f65de094e552276286d7bb417
请有人帮忙!
更新 - 在另一个项目中进行了相同的更改后出现了相同的问题 - 非常奇怪
https://github.com/IceWhaleTech/CasaOS-Gateway/commit/0fae875b3b1ae6fa0825233e9bb6fcfa6e031381
英文:
I've been pulling my hairs for few days on this static linking issue with go build
To reproduce:
- Clone the repo
$ git clone https://github.com/IceWhaleTech/CasaOS-UserService.git
$ cd CasaOS-UserService/
- Checkout the commit where static linking gets broken:
$ git checkout e2d9ecf2299dca7f65de094e552276286d7bb417
- Build
$ CGO_ENABLED=1 go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo ./cmd/migration-tool # Build the code with static linking parameters
$ file migration-tool
migration-tool: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=6bRf1bPBESbFSmuueVEn/fIR_ucgSolvxHG8CoZsj/AAKVZda1Jflk5MBdCj74/Tv1-5IxySthe8moShu27, stripped
> The output shows it's dynamically linked.
- Checkout it's previous commit and build again (with exact the same command)
$ git checkout HEAD~1
$ CGO_ENABLED=1 go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo ./cmd/migration-tool
$ file migration-tool
migration-tool: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=bddccd9307afc326a4645279c9275b6087acc62a, for GNU/Linux 3.2.0, stripped
The build of previous commit is statically linked!
The diff between two commits can be found here
https://github.com/IceWhaleTech/CasaOS-UserService/commit/e2d9ecf2299dca7f65de094e552276286d7bb417
Anyone please help!
UPDATE - the same issue happens after this change in a different project - super weird
https://github.com/IceWhaleTech/CasaOS-Gateway/commit/0fae875b3b1ae6fa0825233e9bb6fcfa6e031381
答案1
得分: 1
找到原因是由于当前提交中对go-sqlite3
的依赖被移除了。由于某种原因,这个移除操作会导致相同的命令无法构建一个静态链接的二进制文件。
虽然我仍然对为什么会这样感到好奇,但一个解决方法是使用一个不依赖CGO的sqlite实现,比如https://pkg.go.dev/modernc.org/sqlite,然后重新构建构建命令,去掉CGO_ENABLED=1
并在tags
中添加osusergo
。
$ go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo,osusergo ./cmd/migration-tool
英文:
Figured out the reason was due to the removal of dependency on go-sqlite3
in the current commit (versus previous commit). For some reason, the removal stops the exact same command from building a static linked binary.
While I'm still curious about why, a workaround is to use a CGO-free sqlite implementation, such as https://pkg.go.dev/modernc.org/sqlite, then reconstruct the build command without CGO_ENABLED=1
and with osusergo
added to tags
.
$ go build --ldflags '-s -w -extldflags "-static"' -tags musl,netgo,osusergo ./cmd/migration-tool
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论