mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-14 02:57:52 +08:00
125 lines
4.6 KiB
Markdown
125 lines
4.6 KiB
Markdown
# Packager's Manual
|
|
|
|
**Note**: The guidance here applies to the current development version and
|
|
release versions starting from 0.16.0. The details for earlier versions are
|
|
different.
|
|
|
|
Elvish is a normal Go application, and doesn't require any special attention.
|
|
Build the main package of `cmd/elvish`, and you should get a fully working
|
|
binary.
|
|
|
|
If you don't care about accurate version information or reproducible builds, you
|
|
can now stop reading. If you do, there is a small amount of extra work to get
|
|
them.
|
|
|
|
## Accurate version information
|
|
|
|
The `pkg/buildinfo` package contains a constant, `Version`, and a variable,
|
|
`VersionSuffix`, which are concatenated to form the full version used in the
|
|
output of `elvish -version` and `elvish -buildinfo`. Their values are set as
|
|
follows:
|
|
|
|
- At release tags, `Version` contains the version of the release, which is
|
|
identical to the tag name. `VersionSuffix` is empty.
|
|
|
|
- At development commits, `Version` contains the version of the next release.
|
|
`VersionSuffix` is set to `-dev.unknown`.
|
|
|
|
The `VersionSuffix` variable can be overridden at build time, by passing
|
|
`-ldflags "-X src.elv.sh/pkg/buildinfo.VersionSuffix=-foobar"` to `go build`,
|
|
`go install` or `go get`. This is necessary in several scenarios, which are
|
|
documented below.
|
|
|
|
### Packaging release versions
|
|
|
|
If you are using the standard Go toolchain and not applying any patches, there
|
|
is nothing more to do; the default empty `VersionSuffix` suffices.
|
|
|
|
If you are using a non-standard toolchain, or have applied any patches that can
|
|
affect the resulting binary, you **must** override `VersionSuffix` with a string
|
|
that starts with `+` and can uniquely identify your toolchain and patch. For
|
|
official Linux distribution builds, this should identify your distribution, plus
|
|
the version of the patch. Example:
|
|
|
|
```sh
|
|
go build -ldflags "-X src.elv.sh/pkg/buildinfo.VersionSuffix=+deb1" ./cmd/elvish
|
|
```
|
|
|
|
### Packaging development builds
|
|
|
|
If you are packaging development builds, the default value of `VersionSuffix`,
|
|
which is `-dev.unknown`, is likely not good enough, as it does not identify the
|
|
commit Elvish is built from.
|
|
|
|
You should override `VersionSuffix` with `-dev.$commit_hash`, where
|
|
`$commit_hash` is the full commit hash, which can be obtained with
|
|
`git rev-parse HEAD`. Example:
|
|
|
|
```sh
|
|
go build -ldflags \
|
|
"-X src.elv.sh/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)" \
|
|
./cmd/elvish
|
|
```
|
|
|
|
If you have applied any patches that is not committed as a Git commit, you
|
|
should also append a string that starts with `+` and can uniquely identify your
|
|
patch.
|
|
|
|
## Reproducible builds
|
|
|
|
The idea of
|
|
[reproducible build](https://en.wikipedia.org/wiki/Reproducible_builds) is that
|
|
an Elvish binary from two different sources should be bit-to-bit identical, as
|
|
long as they are built from the same version of the source code using the same
|
|
version of the Go compiler.
|
|
|
|
To make reproducible builds, you must do the following:
|
|
|
|
- Pass `-trimpath` to the Go compiler.
|
|
|
|
- For the following platforms, also pass `-buildmode=pie` to the Go compiler:
|
|
|
|
- `GOOS=windows`, any `GOARCH`
|
|
|
|
- `GOOS=linux`, `GOARCH=amd64` or `GOARCH=arm64`
|
|
|
|
- Disable cgo by setting the `CGO_ENABLED` environment variable to 0.
|
|
|
|
- Follow the requirements above for putting
|
|
[accurate version information](#accurate-version-information) into the
|
|
binary, so that the user is able to uniquely identify the build by running
|
|
`elvish -version`.
|
|
|
|
The recommendation for how to set `VersionSuffix` when
|
|
[packaging development builds](#packaging-development-builds) becomes hard
|
|
requirements when packaging reproducible builds.
|
|
|
|
In addition, if your distribution uses a patched version of the Go compiler
|
|
that changes its output, or if the build command uses any additional flags
|
|
(either via the command line or via any environment variables), you must
|
|
treat this as a patch on Elvish itself, and supply a version suffix
|
|
accordingly.
|
|
|
|
If you follow these requirements when building Elvish, you can mark the build as
|
|
a reproducible one by overriding `src.elv.sh/pkg/buildinfo.Reproducible` to
|
|
`"true"`.
|
|
|
|
Example when building a release version without any patches, on a platform where
|
|
PIE is applicable:
|
|
|
|
```sh
|
|
go build -buildmode=pie -trimpath \
|
|
-ldflags "-X src.elv.sh/pkg/buildinfo.Reproducible=true" \
|
|
./cmd/elvish
|
|
```
|
|
|
|
Example when building a development version with a patch, on a platform where
|
|
PIE is application:
|
|
|
|
```sh
|
|
go build -buildmode=pie -trimpath \
|
|
-ldflags "-X src.elv.sh/pkg/buildinfo.VersionSuffix=-dev.$(git rev-parse HEAD)+deb0 \
|
|
-X src.elv.sh/pkg/buildinfo.Reproducible=true" \
|
|
./cmd/elvish
|
|
```
|