-
Notifications
You must be signed in to change notification settings - Fork 0
/
run
executable file
·207 lines (161 loc) · 7.29 KB
/
run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/usr/bin/env bash
set -euo pipefail
# https://github.com/ziglang/zig/wiki/Contributing
script_dir=$(cd "${BASH_SOURCE[0]%/*}" && pwd)
args=("$@")
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Env vars that affect this script
# Path to the Zig source repo
src=${src:-/tmp/zig-src}
# Path to the build directory
build_dir=${build_dir:-/tmp/zig-build}
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# All build/test functions in this script place the local zig-cache inside
# $build_dir to avoid cluttering $src.
#
# All build functions are idempotent.
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Build Zig from source, using only a C compiler
#
# The resulting binary is located at $build_dir/stage3/bin/zig
buildBootstrap() {
prepareBuild
ninja install
fixDynamicLinking "$build_dir/stage3/bin/zig"
}
# As a faster alternative to `buildBootstrap`, fetch a prebuilt Zig stage3 binary
usePrebuilt() {
# This creates $build_dir/config.h, required for building Zig
prepareBuild
# This creates $build_dir/zigcpp/libzigcpp.a, required for building Zig
ninja zigcpp
nix build "$script_dir"#zigPrebuiltNoLib -o "$build_dir/helper/stage3-prebuilt"
# Copy instead of symlinking so that the Zig binary automatically picks up
# the Zig lib dir and `config.h` in $build_dir
install -D -T --compare "$build_dir/helper/stage3-prebuilt/zig" "$build_dir/stage3/bin/zig"
}
prepareBuild() {
mkdir -p "$build_dir/helper"
enterDevEnv
cd "$build_dir"
export ZIG_LOCAL_CACHE_DIR=$build_dir/zig-cache
cmake "$src" -DCMAKE_BUILD_TYPE=Release -DZIG_NO_LIB=ON -GNinja
# Required due to -DZIG_NO_LIB=ON, so that zig can find the stdlib
ln -sfn "$src/lib" "$build_dir/lib"
}
# - Set the correct dynamic linker (glibc's ld-linux) from the dev env.
# Zig uses the linker used in /usr/bin/env, which can have the wrong version.
# - Add glibc to the RPATH.
# This is not needed for the dynamic linker to load the correct glibc version
# (because the linker uses the glibc directory in which the linker itself is located).
# But it fixes "wrong version" warnings for glibc in tools like `ldd`, which only use
# resources like RPATH for resolving shared libraries.
fixDynamicLinking() {
binary=$1
patchelf --shrink-rpath \
"$binary"
patchelf --set-interpreter "$(cat "$NIX_BINTOOLS/nix-support/dynamic-linker")" \
--add-rpath "$(cat "$NIX_BINTOOLS/nix-support/orig-libc")/lib" \
"$binary"
}
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Build Zig from source, using the the Zig binary built in `buildBootstrap`.
buildDebug() {
build zig-debug "$@"
}
buildRelease() {
build zig-release -Doptimize=ReleaseFast -Dstrip "$@"
}
build() {
prefix=$1
shift
if [[ ! -e "$build_dir/stage3/bin/zig" ]]; then
echo '`stage3/bin/zig` does not exist. Run one of the following:'
echo 'run buildBootstrap'
echo 'run usePrebuilt'
fi
enterDevEnv
cd $src
printAndRun "$build_dir"/stage3/bin/zig build --prefix "$build_dir/$prefix" \
--cache-dir "$build_dir/zig-cache" -Denable-llvm -Dno-lib "$@"
fixDynamicLinking "$build_dir/$prefix/bin/zig"
}
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
testStdlib() {
zigSrc build test-std -Dskip-release -Dskip-non-native "$@"
}
# Run stdlib tests just for the native CPU
testStdlibFast() {
zigSrc test lib/std/std.zig --zig-lib-dir lib --main-mod-path lib/std "$@"
}
# Basic compiler tests
testBehavior() {
zigSrc build test-behavior -Dskip-non-native "$@"
}
# Basic compiler tests, running just the default Debug configuration
testBehaviorFast() {
zigSrc test test/behavior.zig -I test
}
zigSrc() {
cd $src
zigDebug "$@"
}
zigDebug() {
local cmd=$1
shift
printAndRun "$build_dir/zig-debug/bin/zig" "$cmd" --cache-dir "$build_dir/zig-cache" "$@"
}
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
dev_env=$build_dir/helper/dev-env.sh
dev_env_profile=$build_dir/helper/dev-env-profile
dev_env_src_hash_file=$build_dir/helper/dev-env-src-hash
# Run this script in the Nix dev env
enterDevEnv() {
if [[ ${inZigDevEnv:-} == 1 ]]; then return; fi
src_hash=$(cd $script_dir; sha256sum zig.nix outputs.nix flake.lock)
if [[ ! -e $dev_env || $src_hash != $(cat "$dev_env_src_hash_file" 2>/dev/null || :) ]]; then
# Create dev env
# Cleanup profile links to only save a gcroot to the latest dev env
rm -f "$dev_env_profile"-*-link
mkdir -p "$build_dir/helper"
# Create dev env and save it in a profile to prevent garbage collection. This
# is important so that dynamic libraries linked by Zig don't disappear.
# Use sed to remove `NIX_BUILD_TOP` and tmpdir aliases to `NIX_BUILD_TOP`, so that no
# tmpdir is created each time the the dev env is sourced.
nix print-dev-env --profile "$dev_env_profile" "$script_dir" |
sed -E '/^export (NIX_BUILD_TOP=|\S+=.*?NIX_BUILD_TOP)/d' > "$dev_env"
echo "$src_hash" > "$dev_env_src_hash_file"
fi
# Source dev env file instead of calling `nix develop`:
# - With warm caches and a clean Flake dir, this is 10x faster than `nix develop`.
# `nix develop` introduces a slight but noticeable delay.
# - `nix develop` always evaluates `nixpkgs#bashInteractive`.
# This forces a download of nixpkgs (and a reevaluation of `bashInteractive`) after
# `tarball-ttl` (default: 1 h) which adds an unacceptable delay of many seconds.
. "$dev_env"
exec "${BASH_SOURCE[0]}" "${args[@]}"
}
# Eval a cmd in the dev env
cmd() {
enterDevEnv
eval "$@"
}
printAndRun() {
printf "%q " "$@"; echo
eval "$@"
}
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
case ${1:-} in
''|h|help|-h|--help)
echo "See ./$(realpath --relative-to="$PWD" "$script_dir/usage.sh") for usage"
echo
echo "Info:"
echo "src:"
echo "$src"
echo
echo "build_dir:"
echo "$build_dir"
exit
;;
esac
eval "$@"