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  ```