-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllvm-prebuilt
More file actions
executable file
·577 lines (514 loc) · 22 KB
/
llvm-prebuilt
File metadata and controls
executable file
·577 lines (514 loc) · 22 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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
#!/bin/bash
# llvm_prebuilt.sh: Manages the download and installation of LLVM versions from the GitHub API.
# Requirements: curl, jq, tar
# Source LLVM functions for directory configuration support
SCRIPT_DIR="$(dirname "$0")"
if [ -f "$SCRIPT_DIR/llvm-functions.sh" ]; then
source "$SCRIPT_DIR/llvm-functions.sh"
# Load configuration if .llvmup-config exists
if [ -f ".llvmup-config" ]; then
llvm-config-load >/dev/null 2>&1 || true
fi
fi
# Parse command line arguments
VERBOSE=0
QUIET=0
ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-v|--verbose)
VERBOSE=1
shift
;;
-q|--quiet)
QUIET=1
shift
;;
-h|--help)
echo "Usage: $0 [OPTIONS] [VERSION]"
echo ""
echo "Options:"
echo " -v, --verbose Enable verbose output"
echo " -q, --quiet Suppress non-essential output"
echo " -h, --help Show this help message"
echo ""
echo "Arguments:"
echo " VERSION Version number (1-N) or version tag (e.g., llvmorg-19.1.7)"
echo ""
echo "Examples:"
echo " $0 # Interactive mode"
echo " $0 1 # Install first version in list"
echo " $0 llvmorg-19.1.7 # Install specific version"
echo " $0 -v 1 # Install with verbose output"
exit 0
;;
-*)
echo "Unknown option $1"
exit 1
;;
*)
ARGS+=("$1")
shift
;;
esac
done
# Restore positional parameters
set -- "${ARGS[@]}"
# Logging functions
log_verbose() {
if [ "$VERBOSE" -eq 1 ] && [ "$QUIET" -eq 0 ]; then
echo "[VERBOSE] $*" >&2
fi
}
log_info() {
if [ "$QUIET" -eq 0 ]; then
echo "$*"
fi
}
log_error() {
echo "Error: $*" >&2
}
log_warning() {
if [ "$QUIET" -eq 0 ]; then
echo "Warning: $*" >&2
fi
}
# Check if required commands are installed
command -v curl >/dev/null 2>&1 || {
log_error "The 'curl' command is required but not installed."
log_info "Please install curl using your package manager:"
log_info " Ubuntu/Debian: sudo apt-get install curl"
log_info " Fedora: sudo dnf install curl"
log_info " Arch Linux: sudo pacman -S curl"
exit 1
}
command -v jq >/dev/null 2>&1 || {
log_error "The 'jq' command is required but not installed."
log_info "Please install jq using your package manager:"
log_info " Ubuntu/Debian: sudo apt-get install jq"
log_info " Fedora: sudo dnf install jq"
log_info " Arch Linux: sudo pacman -S jq"
exit 1
}
HAS_TIMEOUT=1
if ! command -v timeout >/dev/null 2>&1; then
HAS_TIMEOUT=0
echo "Warning: The 'timeout' command is not available; continuing without it." >&2
log_verbose "Falling back to a plain curl request without an external timeout wrapper."
if [ "$QUIET" -eq 0 ]; then
log_info "Install GNU coreutils (e.g., 'brew install coreutils') to restore timeout support."
fi
fi
# GitHub API URL for llvm-project releases
API_URL="https://api.github.com/repos/llvm/llvm-project/releases"
log_info "Fetching available LLVM releases from GitHub..."
log_info "This may take a few seconds..."
log_verbose "API URL: $API_URL"
# Show progress for API call with timeout support when available
echo -n "Connecting to GitHub API... "
CURL_ARGS=(
-f
--connect-timeout 30
--max-time 60
--retry 2
--retry-delay 3
--silent
--show-error
"$API_URL"
)
if [ "$HAS_TIMEOUT" -eq 1 ]; then
CURL_CMD=(timeout 60 curl "${CURL_ARGS[@]}")
else
CURL_CMD=(curl "${CURL_ARGS[@]}")
fi
if ! RELEASES=$("${CURL_CMD[@]}" 2>&1); then
echo "FAILED"
log_error "Failed to fetch releases from GitHub."
log_info "This might be due to:"
log_info " - Internet connection issues"
log_info " - GitHub API rate limiting (try again in an hour)"
log_info " - Temporary GitHub service disruption"
log_info " - Firewall or proxy blocking the request"
log_info "Please check your connection and try again."
exit 1
fi
echo "SUCCESS"
log_success "Successfully retrieved release information from GitHub"
log_verbose "API response received ($(echo "$RELEASES" | wc -c) characters)"
# Validate JSON response
if ! echo "$RELEASES" | jq . >/dev/null 2>&1; then
log_error "Invalid JSON response from GitHub API."
log_info "This might indicate a temporary API issue."
if [ "$VERBOSE" -eq 1 ]; then
log_verbose "Response received:"
echo "$RELEASES" | head -5
fi
log_info "Please try again in a few minutes."
exit 1
fi
# Extract available tags (versions)
log_verbose "Extracting version tags from API response..."
VERSIONS=$(echo "$RELEASES" | jq -r '.[].tag_name')
IFS=$'\n' read -rd '' -a versionList <<<"$VERSIONS"
if [ ${#versionList[@]} -eq 0 ]; then
log_error "No LLVM versions found."
log_info "This might be due to:"
log_info " - GitHub API rate limiting"
log_info " - Changes in the LLVM release structure"
log_info " - Temporary GitHub service disruption"
log_info "Please try again in a few minutes."
exit 1
fi
log_verbose "Found ${#versionList[@]} available versions"
log_info "Available versions:"
for i in "${!versionList[@]}"; do
version="${versionList[$i]}"
INSTALLED_FLAG=""
if [ -d "$HOME/.llvm/toolchains/$version" ]; then
INSTALLED_FLAG=" [installed]"
fi
log_info "$((i+1))) $version$INSTALLED_FLAG"
done
# Function to validate and select version based on input
select_version() {
local input="$1"
log_verbose "Validating version input: '$input'"
# If input is a number, use it as an index (1-based)
if [[ "$input" =~ ^[0-9]+$ ]]; then
log_verbose "Input is numeric: $input"
if [ "$input" -ge 1 ] && [ "$input" -le ${#versionList[@]} ]; then
SELECTED_VERSION="${versionList[$((input-1))]}"
log_verbose "Selected version by index: $SELECTED_VERSION"
return 0
else
log_error "Invalid version number '$input'"
log_info "Please select a number between 1 and ${#versionList[@]}"
return 1
fi
else
log_verbose "Input is version tag: $input"
# Otherwise, assume it's a version tag. Check if it exists in the array.
for tag in "${versionList[@]}"; do
if [ "$tag" = "$input" ]; then
SELECTED_VERSION="$tag"
log_verbose "Found matching version tag: $SELECTED_VERSION"
return 0
fi
done
log_error "Invalid version tag '$input'"
log_info "Please provide either a valid version number or a valid version tag from the list above."
return 1
fi
}
# Check if an argument is passed
if [ "$#" -ge 1 ]; then
input="$1"
log_verbose "Using command line argument: $input"
if select_version "$input"; then
log_info "You selected: $SELECTED_VERSION"
else
exit 1
fi
else
# No argument provided: prompt the user
read -p "Select a version by number: " choice
if select_version "$choice"; then
log_info "You selected: $SELECTED_VERSION"
else
exit 1
fi
fi
log_verbose "Starting asset search for version: $SELECTED_VERSION"
# Find the asset containing "Linux-X64.tar.xz" for the selected version
ASSET_URL=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" '
.[] | select(.tag_name == $version) |
.assets[] | select(.name | test("Linux-X64.tar.xz$")) |
.browser_download_url
')
# Try to extract asset digest (if available in the release metadata) to avoid needing a separate checksum file
ASSET_DIGEST=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" --arg name "$(basename "$ASSET_URL")" '
.[] | select(.tag_name == $version) |
.assets[] | select(.browser_download_url == ($name | sub("^"; "https://github.com/" ) )? // .browser_download_url | test("")) |
.digest // empty
')
# Fallback: try to find asset by matching name and read digest
if [ -z "$ASSET_DIGEST" ]; then
ASSET_DIGEST=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" --arg asset "$(basename \"$ASSET_URL\")" '
.[] | select(.tag_name == $version) | .assets[] | select(.name == $asset) | .digest // empty
')
fi
if [ -z "$ASSET_URL" ]; then
log_error "No Linux X64 tarball found for version $SELECTED_VERSION."
log_info "This might be because:"
log_info " - The release doesn't include a Linux X64 build"
log_info " - The asset naming convention has changed"
log_info "Please try a different version or check the LLVM releases page manually."
exit 1
fi
log_info "Download URL found: $ASSET_URL"
log_verbose "Full asset URL: $ASSET_URL"
# Define directories: temporary area and final installation directory
TEMP_DIR="$HOME/llvm_temp/$SELECTED_VERSION"
log_verbose "Creating temporary directory: $TEMP_DIR"
if ! mkdir -p "$TEMP_DIR"; then
log_error "Failed to create temporary directory: $TEMP_DIR"
log_info "Please check if you have write permissions in your home directory."
exit 1
fi
DEST_FILE="$TEMP_DIR/$(basename "$ASSET_URL")"
# Get file size for progress indication
log_info "Getting file information..."
log_verbose "Checking file size at URL: $ASSET_URL"
FILE_SIZE=$(curl -sI "$ASSET_URL" 2>/dev/null | grep -i content-length | awk '{print $2}' | tr -d '\r')
if [ -n "$FILE_SIZE" ]; then
FILE_SIZE_MB=$((FILE_SIZE / 1024 / 1024))
log_info "File size: ${FILE_SIZE_MB}MB"
log_verbose "Raw file size: $FILE_SIZE bytes"
else
log_info "File size: unknown (no Content-Length header)"
fi
log_info "Starting download..."
log_info "This may take several minutes depending on your connection speed."
log_verbose "Downloading to: $DEST_FILE"
# Always show progress bar for downloads, regardless of verbose mode
# Use curl's progress bar which writes to stderr and doesn't interfere with logging
echo "Download progress:"
if ! curl -L \
--progress-bar \
--connect-timeout 30 \
--max-time 3600 \
--retry 3 \
--retry-delay 5 \
"$ASSET_URL" -o "$DEST_FILE"; then
log_error "Failed to download the tarball."
log_info "This could be due to:"
log_info " - Network connectivity issues"
log_info " - GitHub API rate limiting"
log_info " - Invalid or expired download URL"
log_info "Please check your internet connection and try again."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
echo # Add newline after progress bar
log_success "Download completed successfully!"
log_verbose "Downloaded file: $DEST_FILE ($(du -h "$DEST_FILE" | cut -f1))"
log_info "Download finished, performing optional integrity verification..."
# Determine asset base name
ASSET_NAME="$(basename "$ASSET_URL")"
# Honor explicit skip via environment variable (1/true)
if [ -n "$LLVMUP_SKIP_VERIFY" ] && { [ "$LLVMUP_SKIP_VERIFY" = "1" ] || [ "$LLVMUP_SKIP_VERIFY" = "true" ]; }; then
log_info "Skipping verification because LLVMUP_SKIP_VERIFY is set"
VERIFIED=1
else
VERIFIED=0
# If the release metadata contains an asset.digest field, prefer it as the canonical
# expected sha256 fingerprint. Use it first before attempting companion checksum files
# or signatures. If it fails and LLVMUP_REQUIRE_VERIFY is set, abort immediately.
if [ -n "$ASSET_DIGEST" ]; then
log_info "Found asset.digest in release metadata; attempting direct sha256 comparison..."
# normalize expected digest (remove sha256: prefix if present)
EXPECTED_CHKSUM=$(echo "$ASSET_DIGEST" | sed 's/^sha256://I')
# compute actual checksum
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(sha256sum "$DEST_FILE" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(shasum -a 256 "$DEST_FILE" | awk '{print $1}')
else
log_warning "No SHA256 tool available (sha256sum/shasum); cannot verify asset.digest"
ACTUAL_CHKSUM=""
fi
if [ -n "$ACTUAL_CHKSUM" ] && [ "$ACTUAL_CHKSUM" = "$EXPECTED_CHKSUM" ]; then
VERIFIED=1
log_info "asset.digest matches the downloaded file."
else
log_warning "asset.digest did not match the downloaded file. Expected: ${EXPECTED_CHKSUM:-<empty>}, Actual: ${ACTUAL_CHKSUM:-<empty>}"
if [ -n "$LLVMUP_REQUIRE_VERIFY" ] && { [ "$LLVMUP_REQUIRE_VERIFY" = "1" ] || [ "$LLVMUP_REQUIRE_VERIFY" = "true" ]; }; then
log_error "asset.digest verification failed and LLVMUP_REQUIRE_VERIFY is set; aborting."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
fi
fi
# Look for companion assets (.sha256, .sig, .jsonl) in the release metadata
SIG_URL=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" --arg name "$ASSET_NAME" '.[] | select(.tag_name==$version) | .assets[] | select(.name == ($name + ".sig")) | .browser_download_url')
SHA_URL=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" --arg name "$ASSET_NAME" '.[] | select(.tag_name==$version) | .assets[] | select(.name == ($name + ".sha256") or .name == ($name + ".sha256sum") or .name == ($name + ".sha256.txt") or .name == ($name + ".sha256sum.txt")) | .browser_download_url')
JSONL_URL=$(echo "$RELEASES" | jq -r --arg version "$SELECTED_VERSION" --arg name "$ASSET_NAME" '.[] | select(.tag_name==$version) | .assets[] | select(.name == ($name + ".jsonl")) | .browser_download_url')
# Try checksum files first (explicit checksum file)
if [ -n "$SHA_URL" ]; then
log_info "Found checksum asset; attempting sha256 verification..."
if curl -sL "$SHA_URL" -o "$TEMP_DIR/$ASSET_NAME.sha256"; then
CHKSUM_FILE="$TEMP_DIR/$ASSET_NAME.sha256"
# Try to extract a 64-hex sha256
EXPECTED_CHKSUM=$(awk '{print $1}' "$CHKSUM_FILE" | grep -Eo '^[0-9a-f]{64}$' | head -1 || true)
if [ -z "$EXPECTED_CHKSUM" ]; then
# Try to find any 64-hex inside the file
EXPECTED_CHKSUM=$(grep -Eo '[0-9a-f]{64}' "$CHKSUM_FILE" | head -1 || true)
fi
if [ -n "$EXPECTED_CHKSUM" ]; then
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(sha256sum "$DEST_FILE" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(shasum -a 256 "$DEST_FILE" | awk '{print $1}')
else
log_warning "No SHA256 tool available (sha256sum/shasum); cannot verify checksum file"
ACTUAL_CHKSUM=""
fi
if [ -n "$ACTUAL_CHKSUM" ] && [ "$ACTUAL_CHKSUM" = "$EXPECTED_CHKSUM" ]; then
VERIFIED=1
log_info "SHA256 checksum matches."
else
log_warning "SHA256 checksum did not match the downloaded file."
fi
else
log_warning "Checksum file did not contain a recognisable sha256 value."
fi
else
log_warning "Failed to download checksum asset: $SHA_URL"
fi
fi
# If not verified yet, try GPG signature verification
if [ "$VERIFIED" -ne 1 ] && [ -n "$SIG_URL" ]; then
if command -v gpg >/dev/null 2>&1; then
log_info "Found signature asset; attempting GPG verification..."
if curl -sL "$SIG_URL" -o "$TEMP_DIR/$ASSET_NAME.sig"; then
if gpg --verify "$TEMP_DIR/$ASSET_NAME.sig" "$DEST_FILE" >/dev/null 2>&1; then
VERIFIED=1
log_info "GPG signature verified successfully."
else
log_warning "GPG verification failed for signature: $SIG_URL"
fi
else
log_warning "Failed to download signature asset: $SIG_URL"
fi
else
log_warning "gpg not available in PATH; cannot verify signature asset."
fi
fi
# If still not verified, try JSONL attestation (search for sha256 inside)
if [ "$VERIFIED" -ne 1 ] && [ -n "$JSONL_URL" ]; then
log_info "Found JSONL attestation asset; attempting to extract and compare sha256..."
if curl -sL "$JSONL_URL" -o "$TEMP_DIR/$ASSET_NAME.jsonl"; then
EXPECTED_CHKSUM=$(grep -Eo '[0-9a-f]{64}' "$TEMP_DIR/$ASSET_NAME.jsonl" | head -1 || true)
if [ -n "$EXPECTED_CHKSUM" ]; then
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(sha256sum "$DEST_FILE" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL_CHKSUM=$(shasum -a 256 "$DEST_FILE" | awk '{print $1}')
else
log_warning "No SHA256 tool available; cannot verify JSONL attestation"
ACTUAL_CHKSUM=""
fi
if [ -n "$ACTUAL_CHKSUM" ] && [ "$ACTUAL_CHKSUM" = "$EXPECTED_CHKSUM" ]; then
VERIFIED=1
log_info "JSONL attestation sha256 matches the downloaded file."
else
log_warning "JSONL attestation did not match the downloaded file."
fi
else
log_warning "No sha256 fingerprint found in JSONL attestation."
fi
else
log_warning "Failed to download JSONL attestation: $JSONL_URL"
fi
fi
# Final policy enforcement: warn by default, fail only if user requests strict verification
if [ "$VERIFIED" -ne 1 ]; then
if [ -n "$LLVMUP_REQUIRE_VERIFY" ] && { [ "$LLVMUP_REQUIRE_VERIFY" = "1" ] || [ "$LLVMUP_REQUIRE_VERIFY" = "true" ]; }; then
log_error "No successful verification found for downloaded asset and LLVMUP_REQUIRE_VERIFY is set; aborting."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
else
log_warning "No verification available/succeeded for downloaded asset; proceeding (default policy: warn)."
log_info "To require verification, set LLVMUP_REQUIRE_VERIFY=1 in your environment. To skip verification, set LLVMUP_SKIP_VERIFY=1."
fi
fi
fi
log_info "Extracting the archive... (this may take a few moments)"
echo "Extraction progress:"
# Always show some extraction feedback, even in non-verbose mode
if [ "$VERBOSE" -eq 1 ]; then
log_verbose "Extracting with verbose output (showing first 50 files):"
if ! tar -xf "$DEST_FILE" -C "$TEMP_DIR" --verbose 2>&1 | head -50; then
log_error "Failed to extract the tarball."
log_info "The downloaded file might be corrupted. Please try again."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
else
# Show basic extraction progress with a simple progress indicator
echo -n "Extracting files... "
if ! tar -xf "$DEST_FILE" -C "$TEMP_DIR" 2>&1; then
echo "FAILED"
log_error "Failed to extract the tarball."
log_info "The downloaded file might be corrupted. Please try again."
rm -rf "$TEMP_DIR"
exit 1
fi
echo "DONE"
fi
# Identify the extracted folder (assuming the tarball contains a single main folder)
log_verbose "Identifying extracted directory structure..."
EXTRACTED_DIR=$(tar -tf "$DEST_FILE" | head -1 | cut -d/ -f1)
if [ -z "$EXTRACTED_DIR" ]; then
log_error "Failed to identify the extracted directory."
log_info "The tarball structure might be unexpected. Please try again."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
log_verbose "Extracted directory: $EXTRACTED_DIR"
# Define the final installation directory (used by the activation script)
LLVM_TOOLCHAINS_DIR="$(llvm-get-toolchains-dir 2>/dev/null || echo "$HOME/.llvm/toolchains")"
TARGET_DIR="$LLVM_TOOLCHAINS_DIR/$SELECTED_VERSION"
log_info "Preparing final installation directory..."
log_verbose "Target directory: $TARGET_DIR"
# Create the toolchains directory if it doesn't exist
if ! mkdir -p "$LLVM_TOOLCHAINS_DIR"; then
log_error "Failed to create toolchains directory: $LLVM_TOOLCHAINS_DIR"
log_info "Please check if you have write permissions in your home directory."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
# Move the extracted folder to the final directory
log_info "Installing LLVM to final location..."
log_verbose "Moving from: $TEMP_DIR/$EXTRACTED_DIR"
log_verbose "Moving to: $TARGET_DIR"
if ! mv "$TEMP_DIR/$EXTRACTED_DIR" "$TARGET_DIR"; then
log_error "Failed to move the extracted files to the target directory."
log_info "Please check if you have write permissions in your home directory."
log_verbose "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
exit 1
fi
log_info "LLVM $SELECTED_VERSION installed in $TARGET_DIR."
# Clean up temporary files
log_verbose "Cleaning up temporary files: $TEMP_DIR"
if ! rm -rf "$TEMP_DIR"; then
log_warning "Failed to clean up temporary files in $TEMP_DIR"
log_info "You can safely delete this directory manually."
fi
log_info ""
log_success "Installation completed successfully!"
log_info "Run 'llvm-activate $SELECTED_VERSION' to activate the installed version."
log_info ""
# Verify installation
if [ -f "$TARGET_DIR/bin/clang" ]; then
log_info "Installation verification: clang binary found ✓"
if [ "$VERBOSE" -eq 1 ]; then
log_verbose "clang version info:"
"$TARGET_DIR/bin/clang" --version 2>/dev/null | head -3
fi
else
log_warning "Installation verification: clang binary not found in expected location"
log_info "LLVM might have been installed with a different structure."
log_info "Check $TARGET_DIR for the actual binaries."
if [ "$VERBOSE" -eq 1 ]; then
log_verbose "Contents of installation directory:"
ls -la "$TARGET_DIR" 2>/dev/null || log_verbose "Directory listing failed"
fi
fi