|
9 | 9 | set -euo pipefail |
10 | 10 |
|
11 | 11 | if [[ "${CI:-}" == "true" ]]; then |
12 | | - set -x |
| 12 | + set -x |
13 | 13 | fi |
14 | 14 |
|
15 | 15 | # Locate a bootstrap toolchain and (re)build gocross if necessary. We run all of |
16 | 16 | # this in a subshell because posix shell semantics make it very easy to |
17 | 17 | # accidentally mutate the input environment that will get passed to gocross at |
18 | 18 | # the bottom of this script. |
19 | 19 | ( |
20 | | -repo_root="${BASH_SOURCE%/*}/../.." |
21 | | - |
22 | | -# Figuring out if gocross needs a rebuild, as well as the rebuild itself, need |
23 | | -# to happen with CWD inside this repo. Since we're in a subshell entirely |
24 | | -# dedicated to wrangling gocross and toolchains, cd over now before doing |
25 | | -# anything further so that the rest of this logic works the same if gocross is |
26 | | -# being invoked from somewhere else. |
27 | | -cd "$repo_root" |
28 | | - |
29 | | -toolchain="$HOME/.cache/tailscale-go" |
30 | | - |
31 | | -if [[ -d "$toolchain" ]]; then |
32 | | - # A toolchain exists, but is it recent enough to compile gocross? If not, |
33 | | - # wipe it out so that the next if block fetches a usable one. |
34 | | - want_go_minor=$(grep -E '^go ' "go.mod" | cut -f2 -d'.') |
35 | | - have_go_minor=$(head -1 "$toolchain/VERSION" | cut -f2 -d'.') |
36 | | - # Shortly before stable releases, we run release candidate |
37 | | - # toolchains, which have a non-numeric suffix on the version |
38 | | - # number. Remove the rc qualifier, we just care about the minor |
39 | | - # version. |
40 | | - have_go_minor="${have_go_minor%rc*}" |
41 | | - if [[ -z "$have_go_minor" || "$have_go_minor" -lt "$want_go_minor" ]]; then |
42 | | - rm -rf "$toolchain" "$toolchain.extracted" |
| 20 | + repo_root="${BASH_SOURCE%/*}/../.." |
| 21 | + |
| 22 | + # Figuring out if gocross needs a rebuild, as well as the rebuild itself, need |
| 23 | + # to happen with CWD inside this repo. Since we're in a subshell entirely |
| 24 | + # dedicated to wrangling gocross and toolchains, cd over now before doing |
| 25 | + # anything further so that the rest of this logic works the same if gocross is |
| 26 | + # being invoked from somewhere else. |
| 27 | + cd "$repo_root" |
| 28 | + |
| 29 | + # Binaries run with `gocross run` can reinvoke gocross, resulting in a |
| 30 | + # potentially fancy build that invokes external linkers, might be |
| 31 | + # cross-building for other targets, and so forth. In one hilarious |
| 32 | + # case, cmd/cloner invokes go with GO111MODULE=off at some stage. |
| 33 | + # |
| 34 | + # Anyway, build gocross in a stripped down universe. |
| 35 | + gocross_path="gocross" |
| 36 | + gocross_ok=0 |
| 37 | + wantver="$(git rev-parse HEAD)" |
| 38 | + if [[ -x "$gocross_path" ]]; then |
| 39 | + gotver="$($gocross_path gocross-version 2>/dev/null || echo '')" |
| 40 | + if [[ "$gotver" == "$wantver" ]]; then |
| 41 | + gocross_ok=1 |
43 | 42 | fi |
44 | | -fi |
45 | | -if [[ ! -d "$toolchain" ]]; then |
46 | | - mkdir -p "$HOME/.cache" |
47 | | - |
48 | | - # We need any Go toolchain to build gocross, but the toolchain also has to |
49 | | - # be reasonably recent because we upgrade eagerly and gocross might not |
50 | | - # build with Go N-1. So, if we have no cached tailscale toolchain at all, |
51 | | - # fetch the initial one in shell. Once gocross is built, it'll manage |
52 | | - # updates. |
53 | | - read -r REV <go.toolchain.rev |
54 | | - |
55 | | - case "$REV" in |
56 | | - /*) |
57 | | - toolchain="$REV" |
58 | | - ;; |
59 | | - *) |
60 | | - # This works for linux and darwin, which is sufficient |
61 | | - # (we do not build tailscale-go for other targets). |
62 | | - HOST_OS=$(uname -s | tr A-Z a-z) |
63 | | - HOST_ARCH="$(uname -m)" |
64 | | - if [[ "$HOST_ARCH" == "aarch64" ]]; then |
65 | | - # Go uses the name "arm64". |
66 | | - HOST_ARCH="arm64" |
67 | | - elif [[ "$HOST_ARCH" == "x86_64" ]]; then |
68 | | - # Go uses the name "amd64". |
69 | | - HOST_ARCH="amd64" |
70 | | - fi |
71 | | - |
72 | | - rm -rf "$toolchain" "$toolchain.extracted" |
73 | | - curl -f -L -o "$toolchain.tar.gz" "https://github.com/tailscale/go/releases/download/build-${REV}/${HOST_OS}-${HOST_ARCH}.tar.gz" |
74 | | - mkdir -p "$toolchain" |
75 | | - (cd "$toolchain" && tar --strip-components=1 -xf "$toolchain.tar.gz") |
76 | | - echo "$REV" >"$toolchain.extracted" |
77 | | - rm -f "$toolchain.tar.gz" |
78 | | - ;; |
79 | | - esac |
80 | | -fi |
81 | | - |
82 | | -# Binaries run with `gocross run` can reinvoke gocross, resulting in a |
83 | | -# potentially fancy build that invokes external linkers, might be |
84 | | -# cross-building for other targets, and so forth. In one hilarious |
85 | | -# case, cmd/cloner invokes go with GO111MODULE=off at some stage. |
86 | | -# |
87 | | -# Anyway, build gocross in a stripped down universe. |
88 | | -gocross_path="gocross" |
89 | | -gocross_ok=0 |
90 | | -wantver="$(git rev-parse HEAD)" |
91 | | -if [[ -x "$gocross_path" ]]; then |
92 | | - gotver="$($gocross_path gocross-version 2>/dev/null || echo '')" |
93 | | - if [[ "$gotver" == "$wantver" ]]; then |
94 | | - gocross_ok=1 |
95 | | - fi |
96 | | -fi |
97 | | -if [[ "$gocross_ok" == "0" ]]; then |
| 43 | + fi |
| 44 | + if [[ "$gocross_ok" == "0" ]]; then |
98 | 45 | unset GOOS |
99 | 46 | unset GOARCH |
100 | 47 | unset GO111MODULE |
101 | 48 | unset GOROOT |
102 | 49 | export CGO_ENABLED=0 |
103 | | - "$toolchain/bin/go" build -o "$gocross_path" -ldflags "-X tailscale.com/version.gitCommitStamp=$wantver" tailscale.com/tool/gocross |
104 | | -fi |
| 50 | + go build -o "$gocross_path" -ldflags "-X tailscale.com/version.gitCommitStamp=$wantver" tailscale.com/tool/gocross |
| 51 | + fi |
105 | 52 | ) # End of the subshell execution. |
106 | 53 |
|
107 | 54 | exec "${BASH_SOURCE%/*}/../../gocross" "$@" |
0 commit comments