その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

GNU Goldのリンカがdeprecatedになる予定だそうなので暫定的にcgoでGNU ldの利用を明示する

www.phoronix.com

ということで、GNU Goldのリンカがdeprecatedになる予定だそうです。

arm64環境のgo *1 でcgoを利用しようとするとデフォルトでgoldのリンカを利用しようとするので、これをGNU ldを使うようにしたいという話です。かつてのGNU ldにはshow stopperとなるバグが存在していましたが、少なくともバージョン2.35以降のGNU ldであれば利用しても良い状況となっているという理解です。
この裏にあるテーマとしてはAmazon Linux 2023だとgoldのbinutilsがシュッと入らず、GNU ldはあるけどgold ldが無いとcgoを使うツールのビルドでfailするという問題があり……このためにいちいちfedoraのrepoを追加するのも面倒なので。

[FYI] goldのldが無いとこのようにコケる:

$ go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5
# github.com/golangci/golangci-lint/cmd/golangci-lint
/usr/local/go/pkg/tool/linux_arm64/link: running gcc failed: exit status 1
/usr/bin/gcc -Wl,-z,now -Wl,-z,nocopyreloc -fuse-ld=gold -Wl,--build-id=0x7c06cf55d9e31c7aa2dab2e997ce40f506533556 -o $WORK/b001/exe/a.out -rdynamic /tmp/go-link-748591831/go.o /tmp/go-link-748591831/000000.o /tmp/go-link-748591831/000001.o /tmp/go-link-748591831/000002.o /tmp/go-link-748591831/000003.o /tmp/go-link-748591831/000004.o /tmp/go-link-748591831/000005.o /tmp/go-link-748591831/000006.o /tmp/go-link-748591831/000007.o /tmp/go-link-748591831/000008.o /tmp/go-link-748591831/000009.o /tmp/go-link-748591831/000010.o /tmp/go-link-748591831/000011.o /tmp/go-link-748591831/000012.o /tmp/go-link-748591831/000013.o /tmp/go-link-748591831/000014.o /tmp/go-link-748591831/000015.o /tmp/go-link-748591831/000016.o /tmp/go-link-748591831/000017.o /tmp/go-link-748591831/000018.o /tmp/go-link-748591831/000019.o /tmp/go-link-748591831/000020.o /tmp/go-link-748591831/000021.o /tmp/go-link-748591831/000022.o /tmp/go-link-748591831/000023.o /tmp/go-link-748591831/000024.o -O2 -g -lresolv -O2 -g -ldl -O2 -g -lpthread -O2 -g
collect2: fatal error: cannot find 'ld'

というわけでGNU ldを使うようにするには、

  • -ldflags="-extldflags=-fuse-ld=bfd" をオプションとして指定する (e.g. go install -ldflags="-extldflags=-fuse-ld=bfd" github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5)
  • CGO_LDFLAGS="-fuse-ld=bfd"環境変数として指定する

という2つの方法があり、用途に応じて使い分けると良さそうに思いました。我々のユースケースではdocker containerとして環境を作っているのでcontainerの構築時に環境変数を指定する感じで運用することとしています。

なおこのあたりは処理系のほうでも議論が成されているようで、

github.com

https://go-review.googlesource.com/c/go/+/391115

このパッチが入るとこのようなワークアラウンドは不要になるのではないかと思います。

*1:もしかしたらarm64以外もそうかも?