github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/PACKAGING.md (about) 1 # Packager's Manual 2 3 **Note**: The guidance here applies to the current development version and 4 release versions starting from 0.16.0. The details for earlier versions are 5 different. 6 7 Elvish is a normal Go application, and doesn't require any special attention. 8 Build the main package of `cmd/elvish`, and you should get a fully working 9 binary. 10 11 If you don't care about accurate version information or reproducible builds, you 12 can now stop reading. If you do, there is a small amount of extra work to get 13 them. 14 15 ## Accurate version information 16 17 The `pkg/buildinfo` package contains a constant, `Version`, and a variable, 18 `VersionSuffix`, which are concatenated to form the full version used in the 19 output of `elvish -version` and `elvish -buildinfo`. Their values are set as 20 follows: 21 22 - At release tags, `Version` contains the version of the release, which is 23 identical to the tag name. `VersionSuffix` is empty. 24 25 - At development commits, `Version` contains the version of the next release. 26 `VersionSuffix` is set to `-dev.unknown`. 27 28 The `VersionSuffix` variable can be overridden at build time, by passing 29 `-ldflags "-X github.com/markusbkk/elvish/pkg/buildinfo.VersionSuffix=-foobar"` to `go build`, 30 `go install` or `go get`. This is necessary in several scenarios, which are 31 documented below. 32 33 ### Packaging release versions 34 35 If you are using the standard Go toolchain and not applying any patches, there 36 is nothing more to do; the default empty `VersionSuffix` suffices. 37 38 If you are using a non-standard toolchain, or have applied any patches that can 39 affect the resulting binary, you **must** override `VersionSuffix` with a string 40 that starts with `+` and can uniquely identify your toolchain and patch. For 41 official Linux distribution builds, this should identify your distribution, plus 42 the version of the patch. Example: 43 44 ```sh 45 go build -ldflags "-X github.com/markusbkk/elvish/pkg/buildinfo.VersionSuffix=+deb1" ./cmd/elvish 46 ``` 47 48 ### Packaging development builds 49 50 If you are packaging development builds, the default value of `VersionSuffix`, 51 which is `-dev.unknown`, is likely not good enough, as it does not identify the 52 commit Elvish is built from. 53 54 You should override `VersionSuffix` with `-dev.$commit_hash`, where 55 `$commit_hash` is the full commit hash, which can be obtained with 56 `git rev-parse HEAD`. Example: 57 58 ```sh 59 go build -ldflags \ 60 "-X github.com/markusbkk/elvish/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)" \ 61 ./cmd/elvish 62 ``` 63 64 If you have applied any patches that is not committed as a Git commit, you 65 should also append a string that starts with `+` and can uniquely identify your 66 patch. 67 68 ## Reproducible builds 69 70 The idea of 71 [reproducible build](https://en.wikipedia.org/wiki/Reproducible_builds) is that 72 an Elvish binary from two different sources should be bit-to-bit identical, as 73 long as they are built from the same version of the source code using the same 74 version of the Go compiler. 75 76 To make reproducible builds, you must do the following: 77 78 - Pass `-trimpath` to the Go compiler. 79 80 - For the following platforms, also pass `-buildmode=pie` to the Go compiler: 81 82 - `GOOS=windows`, any `GOARCH` 83 84 - `GOOS=linux`, `GOARCH=amd64` or `GOARCH=arm64` 85 86 - Disable cgo by setting the `CGO_ENABLED` environment variable to 0. 87 88 - Follow the requirements above for putting 89 [accurate version information](#accurate-version-information) into the 90 binary, so that the user is able to uniquely identify the build by running 91 `elvish -version`. 92 93 The recommendation for how to set `VersionSuffix` when 94 [packaging development builds](#packaging-development-builds) becomes hard 95 requirements when packaging reproducible builds. 96 97 In addition, if your distribution uses a patched version of the Go compiler 98 that changes its output, or if the build command uses any additional flags 99 (either via the command line or via any environment variables), you must 100 treat this as a patch on Elvish itself, and supply a version suffix 101 accordingly. 102 103 If you follow these requirements when building Elvish, you can mark the build as 104 a reproducible one by overriding `github.com/markusbkk/elvish/pkg/buildinfo.Reproducible` to 105 `"true"`. 106 107 Example when building a release version without any patches, on a platform where 108 PIE is applicable: 109 110 ```sh 111 go build -buildmode=pie -trimpath \ 112 -ldflags "-X github.com/markusbkk/elvish/pkg/buildinfo.Reproducible=true" \ 113 ./cmd/elvish 114 ``` 115 116 Example when building a development version with a patch, on a platform where 117 PIE is application: 118 119 ```sh 120 go build -buildmode=pie -trimpath \ 121 -ldflags "-X github.com/markusbkk/elvish/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)+deb0 \ 122 -X github.com/markusbkk/elvish/pkg/buildinfo.Reproducible=true" \ 123 ./cmd/elvish 124 ```