Search code examples
gostatic-linkinggoreleaser

How can I reproduce a goreleaser run locally?


Context: there's a repo that uses GoReleaser tool that compiles binaries and releases it to GitHub.

As described in this issue, a commit tagged v1.32.0 resulted in a release with dynamically linked binaries -- and that's OK: for example, if you download the terraform-provider-confluent_1.32.0_linux_amd64 binary and then run file command you'd see "dynamically linked":

$ file ~/MyDownloads/terraform-provider-confluent_1.32.0_linux_amd64/terraform-provider-confluent_1.32.0
/Users/klinou/MyDownloads/terraform-provider-confluent_1.32.0_linux_amd64/terraform-provider-confluent_1.32.0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=8SfNWb1Abn_y718BUN-I/PH1ZOJTKh7G-G89wQMVi/7pnMTwFFJzGpJwJM40fD/vwMzK5ZvGUHoFFCvKApk, stripped

I've been trying to update .goreleaser config to generate a statically linked binary. But the issue is I can't even reproduce "dynamically linked" message when running a GoReleaser tool locally:

$ git clone https://github.com/confluentinc/terraform-provider-confluent.git
$ cd terraform-provider-confluent
$ git checkout v1.32.0
$ git log --pretty=oneline | head -n 2
77e1ff645b2beb7c723d72e8a3a45404a86540ab chore: minor version bump v1.32.0
8794b8e9db91abc0386463824349dbbdca406917 #minor Prepare for 1.32.0 release (#382)
$ goreleaser build
   • building...
   • loading config file       file=.goreleaser.yml
   • loading environment variables
   • getting and validating git state
      • building...               commit=77e1ff645b2beb7c723d72e8a3a45404a86540ab latest tag=v1.32.0
   • parsing tag
...
      • building                  binary=dist/terraform-provider-confluent-internal_freebsd_arm_6/terraform-provider-confluent-internal_1.32.0
      • building                  binary=dist/terraform-provider-confluent-internal_windows_arm_6/terraform-provider-confluent-internal_1.32.0.exe
      • building                  binary=dist/terraform-provider-confluent-internal_linux_arm64/terraform-provider-confluent-internal_1.32.0
      • building                  binary=dist/terraform-provider-confluent-internal_windows_arm64/terraform-provider-confluent-internal_1.32.0.exe
   • storing release metadata
      • writing                   file=dist/artifacts.json
      • writing                   file=dist/metadata.json
   • build succeeded after 185.72s
$ file dist/terraform-provider-confluent-internal_linux_amd64/terraform-provider-confluent-internal_1.32.0
dist/terraform-provider-confluent-internal_linux_amd64/terraform-provider-confluent-internal_1.32.0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=mcIeopVb5rXUWUc_eSUS/j1Bzyx4mWzFzh_9rKrtG/KancpatKw1cE9IjTQJmA/t6Dl2Mx7-b1wnGTxHaMx, stripped

And in the end, I can see statically linked and not dynamically linked for file command. What should I fix (GoReleaser command?) to reproduce a "remote" run of a GoReleaser to see dynamically linked?

Update: https://github.com/zambien/terraform-provider-apigee/issues/48 seems to be relevant.


Solution

  • On v1.32.0 you had a typo in CGO_ENABLED, so, in fact, there was no value set for it.

    https://github.com/confluentinc/terraform-provider-confluent/blob/v1.32.0/.goreleaser.yml#L32

    If you go build locally for the same OS without setting any value for CGO_ENABLED, the binary will be dynamically linked, and if you build for another GOOS (let's say, from darwin you set GOOS=linux), it'll be statically linked.

    So, this has very little to do with GoReleaser per se, and more about the Go toolchain and a typo.

    Answering your question, if you set CGO_ENABLED=1 on your GoReleaser's configuration file, you should be able to reproduce it locally. I would advise to use --skip-publish though, as you probably don't want to be re-publishing artifacts every time.