-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.sh
More file actions
executable file
·236 lines (186 loc) · 5.6 KB
/
bootstrap.sh
File metadata and controls
executable file
·236 lines (186 loc) · 5.6 KB
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
die() {
printf '%s\n' "$1" >&2
exit 1
}
list_versions() {
local found=false
for dir in "$SCRIPT_DIR"/*/; do
[[ -d "$dir" ]] || continue
local name
name="$(basename "$dir")"
if [[ "$name" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
printf ' %s\n' "$name"
found=true
fi
done
if [[ "$found" == false ]]; then
printf ' No version folders found\n'
fi
}
show_usage() {
cat <<'EOF'
Usage: ./bootstrap.sh <version> <target> <mcpu>
./bootstrap.sh clean <version> <target> <mcpu>
Examples:
./bootstrap.sh 0.15.2 aarch64-macos-none baseline
./bootstrap.sh clean 0.15.2 aarch64-linux-gnu baseline
Available versions:
EOF
list_versions
}
download_file() {
local url="$1"
local output="$2"
if command -v wget >/dev/null 2>&1; then
wget "$url" -c -O "$output"
return
fi
if command -v curl >/dev/null 2>&1; then
curl -L "$url" -o "$output"
return
fi
die "Error: neither wget nor curl is available"
}
apply_patches() {
local patch_dir="$1"
local patch_file
local -a patch_files=()
local -a sorted_patch_files=()
if [[ -d "$patch_dir" ]]; then
shopt -s nullglob
patch_files=("$patch_dir"/*.patch)
shopt -u nullglob
fi
if [[ ${#patch_files[@]} -gt 0 ]]; then
while IFS= read -r patch_file; do
sorted_patch_files+=("$patch_file")
done < <(printf '%s\n' "${patch_files[@]}" | LC_ALL=C sort)
printf 'Applying %s patch file(s) from %s\n' "${#sorted_patch_files[@]}" "$patch_dir"
for patch_file in "${sorted_patch_files[@]}"; do
printf ' applying %s\n' "$(basename "$patch_file")"
patch -p1 <"$patch_file"
done
printf 'patches applied successfully\n'
return
fi
die "Error: no patch files found in '$patch_dir'"
}
if [[ $# -eq 0 ]]; then
show_usage >&2
exit 1
fi
if [[ "$1" == "clean" ]]; then
if [[ $# -ne 4 ]]; then
die "Error: clean requires <version> <target> <mcpu>"
fi
VERSION_DIR="$2"
CLEAN_TARGET="$3"
CLEAN_MCPU="$4"
VERSION_PATH="$SCRIPT_DIR/$VERSION_DIR"
if [[ ! -d "$VERSION_PATH" ]]; then
die "Error: Version directory '$VERSION_DIR' does not exist"
fi
BUILD_DIR="$VERSION_PATH/.build-${CLEAN_TARGET}-${CLEAN_MCPU}"
VERSION_OUT_DIR="$VERSION_PATH/.out/zig-${CLEAN_TARGET}-${CLEAN_MCPU}"
ROOT_OUT_DIR="$SCRIPT_DIR/.out/zig-${CLEAN_TARGET}-${CLEAN_MCPU}"
printf 'Cleaning %s for target=%s mcpu=%s...\n' "$VERSION_DIR" "$CLEAN_TARGET" "$CLEAN_MCPU"
for dir in "$BUILD_DIR" "$VERSION_OUT_DIR" "$ROOT_OUT_DIR"; do
if [[ -e "$dir" ]]; then
printf ' Removing %s...\n' "$dir"
rm -rf "$dir"
fi
done
printf 'Clean complete!\n'
exit 0
fi
if [[ $# -ne 3 ]]; then
show_usage >&2
exit 1
fi
VERSION_DIR="$1"
TARGET="$2"
MCPU="$3"
VERSION_PATH="$SCRIPT_DIR/$VERSION_DIR"
if [[ ! -d "$VERSION_PATH" ]]; then
die "Error: Version directory '$VERSION_DIR' does not exist"
fi
cd "$VERSION_PATH"
printf 'Working in: %s\n\n' "$VERSION_PATH"
printf '=== Step 1: Downloading and Extracting ===\n'
mkdir -p .downloads
pushd .downloads >/dev/null
if [[ ! -d llvm-project ]]; then
llvm_url="$(sed -n '1p' ../llvm-project)"
[[ -n "$llvm_url" ]] || die "Error: ./llvm-project source definition is empty"
printf 'Downloading llvm-project...\n'
download_file "$llvm_url" llvm-project.tar.gz
mkdir -p llvm-project
tar -xf llvm-project.tar.gz --strip-components=1 -C llvm-project
else
printf 'Using cached llvm-project\n'
fi
if [[ ! -d zig-bootstrap ]]; then
zig_source="$(sed -n '1p' ../zig-bootstrap)"
zig_ref="$(sed -n '2p' ../zig-bootstrap)"
[[ -n "$zig_source" ]] || die "Error: ./zig-bootstrap source definition is empty"
if [[ "$zig_source" == *.tar.gz ]]; then
printf 'Downloading zig-bootstrap via tarball...\n'
download_file "$zig_source" zig-bootstrap.tar.gz
mkdir -p zig-bootstrap
tar -xf zig-bootstrap.tar.gz --strip-components=1 -C zig-bootstrap
else
[[ -n "$zig_ref" ]] || die "Error: git source requires ref on line 2 in ./zig-bootstrap"
printf 'Cloning zig-bootstrap (shallow) from %s tag: %s...\n' "$zig_source" "$zig_ref"
git clone --depth 1 --branch "$zig_ref" "$zig_source" zig-bootstrap
fi
else
printf 'Using cached zig-bootstrap\n'
fi
popd >/dev/null
printf '\n=== Step 2: Creating build folder ===\n'
BUILD_DIR=".build-${TARGET}-${MCPU}"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
pushd "$BUILD_DIR" >/dev/null
cp -R ../.downloads/zig-bootstrap/zig zig
cp -R ../.downloads/zig-bootstrap/zlib zlib
cp -R ../.downloads/zig-bootstrap/zstd zstd
cp -R ../.downloads/zig-bootstrap/build build
cp -R ../.downloads/llvm-project/llvm llvm
cp -R ../.downloads/llvm-project/clang clang
cp -R ../.downloads/llvm-project/lld lld
cp -R ../.downloads/llvm-project/cmake cmake
if [[ -d ../.downloads/llvm-project/third-party ]]; then
cp -R ../.downloads/llvm-project/third-party third-party
fi
printf '\n=== Step 3: Applying patch to %s ===\n' "$BUILD_DIR"
apply_patches "../patches"
printf '\n=== Step 4: Building Zig ===\n'
if command -v nproc >/dev/null 2>&1; then
CPU_CORES="$(nproc)"
elif command -v sysctl >/dev/null 2>&1; then
CPU_CORES="$(sysctl -n hw.ncpu)"
else
CPU_CORES=4
fi
if [[ "$CPU_CORES" -gt 8 ]]; then
CPU_CORES=8
fi
export CMAKE_BUILD_PARALLEL_LEVEL="$CPU_CORES"
printf 'Using %s parallel jobs for compilation\n' "$CPU_CORES"
export PKG_CONFIG_PATH=""
export PKG_CONFIG_LIBDIR=""
./build "$TARGET" "$MCPU"
popd >/dev/null
printf '\n=== Copying output to .out/ ===\n'
ROOT_OUT_DIR="$SCRIPT_DIR/.out"
ROOT_OUT_PATH="$ROOT_OUT_DIR/zig-${TARGET}-${MCPU}"
mkdir -p "$ROOT_OUT_DIR"
rm -rf "$ROOT_OUT_PATH"
cp -R "$BUILD_DIR/out/zig-${TARGET}-${MCPU}" "$ROOT_OUT_DIR/"
printf '\n=== Build Complete ===\n'
printf 'Output: %s\n' "$ROOT_OUT_PATH"
ls -la "$ROOT_OUT_PATH"