wxh
wxh

Reputation: 808

No longer able to build static linked binary with exact same `go build` command after some code change, but why?

I've been pulling my hairs for few days on this static linking issue with go build

To reproduce:

  1. Clone the repo
$ git clone https://github.com/IceWhaleTech/CasaOS-UserService.git
$ cd CasaOS-UserService/
  1. Checkout the commit where static linking gets broken:
$ git checkout e2d9ecf2299dca7f65de094e552276286d7bb417
  1. 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.

  1. 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

Upvotes: 1

Views: 828

Answers (1)

wxh
wxh

Reputation: 808

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

Upvotes: 1

Related Questions