github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/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 overriden at build time, by passing
    29  `-ldflags "-X src.elv.sh/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 not applying any patches, there is nothing to do. The default value
    36  of `VersionSuffix`, which is empty, suffices.
    37  
    38  If you have applied any patches, you **must** override `VersionSuffix` with a
    39  string that starts with `+` and can uniquely identify your patch. For official
    40  Linux distribution builds, this should identify your distribution, plus the
    41  version of the patch. Example:
    42  
    43  ```sh
    44  go build -ldflags "-X src.elv.sh/pkg/buildinfo.VersionSuffix=+deb1" ./cmd/elvish
    45  ```
    46  
    47  ### Packaging development builds
    48  
    49  If you are packaging development builds, the default value of `VersionSuffix`,
    50  which is `-dev.unknown`, is likely not good enough, as it does not identify the
    51  commit Elvish is built from.
    52  
    53  You should override `VersionSuffix` with `-dev.$commit_hash`, where
    54  `$commit_hash` is the full commit hash, which can be obtained with
    55  `git rev-parse HEAD`. Example:
    56  
    57  ```sh
    58  go build -ldflags \
    59    "-X src.elv.sh/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)" \
    60    ./cmd/elvish
    61  ```
    62  
    63  If you have applied any patches that is not committed as a Git commit, you
    64  should also append a string that starts withs `+` and can uniquely identify your
    65  patch.
    66  
    67  ## Reproducible builds
    68  
    69  The idea of
    70  [reproducible build](https://en.wikipedia.org/wiki/Reproducible_builds) is that
    71  an Elvish binary from two different sources should be bit-to-bit identical, as
    72  long as they are built from the same version of the source code using the same
    73  version of the Go compiler.
    74  
    75  To make reproducible builds, you must do the following:
    76  
    77  -   Pass `-trimpath` to the Go compiler.
    78  
    79  -   For the following platforms, also pass `-buildmode=pie` to the Go compiler:
    80  
    81      -   `GOOS=windows`, any `GOARCH`
    82  
    83      -   `GOOS=linux`, `GOARCH=amd64` or `GOARCH=arm64`
    84  
    85  -   Disable cgo by setting the `CGO_ENABLED` environment variable to 0.
    86  
    87  -   Follow the requirements above for putting
    88      [accurate version information](#accurate-version-information) into the
    89      binary, so that the user is able to uniquely identify the build by running
    90      `elvish -version`.
    91  
    92      The recommendation for how to set `VersionSuffix` when
    93      [packaging development builds](#packaging-development-builds) becomes hard
    94      requirements when packaging reproducible builds.
    95  
    96      In addition, if your distribution uses a patched version of the Go compiler
    97      that changes its output, or if the build command uses any additional flags
    98      (either via the command line or via any environment variables), you must
    99      treat this as a patch on Elvish itself, and supply a version suffix
   100      accordingly.
   101  
   102  If you follow these requirements when building Elvish, you can mark the build as
   103  a reproducible one by overriding `src.elv.sh/pkg/buildinfo.Reproducible` to
   104  `"true"`.
   105  
   106  Example when building a release version without any patches, on a platform where
   107  PIE is applicable:
   108  
   109  ```sh
   110  go build -buildmode=pie -trimpath \
   111    -ldflags "-X src.elv.sh/pkg/buildinfo.Reproducible=true" \
   112    ./cmd/elvish
   113  ```
   114  
   115  Example when building a development version with a patch, on a platform where
   116  PIE is application:
   117  
   118  ```sh
   119  go build -buildmode=pie -trimpath \
   120    -ldflags "-X src.elv.sh/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)+deb0 \
   121              -X src.elv.sh/pkg/buildinfo.Reproducible=true" \
   122    ./cmd/elvish
   123  ```