11#! /usr/bin/env bash
2+ # PGO+BOLT optimized build script for cargo-dist integration.
3+ # All output goes to stderr except the final cargo build which uses JSON output for cargo-dist.
4+ #
5+ # On Linux x86_64: Does full PGO+BOLT optimization
6+ # On other platforms: Falls back to regular cargo build (PGO/BOLT not supported)
27set -euo pipefail
38
9+ # Redirect all output to stderr by default
10+ exec 3>&1 1>&2
11+
412cd " $( dirname " $0 " ) /../.."
513
6- PROFILE=" ${PROFILE:- dist} "
7- FEATURES=" ${FEATURES:- cli,asm,mimalloc} "
14+ # Parse cargo-dist args passed via environment or command line
15+ # Expected format: build --profile dist --message-format=json-render-diagnostics --target <triple> ...
16+ CARGO_DIST_ARGS=" ${CARGO_DIST_ARGS:- } "
17+
18+ # Extract useful info from cargo-dist args
19+ TARGET=" "
20+ PROFILE=" dist"
21+ FEATURES=" "
22+ MESSAGE_FORMAT=" "
23+ OTHER_ARGS=()
24+
25+ parse_args () {
26+ local args=($CARGO_DIST_ARGS )
27+ local i=0
28+ while [[ $i -lt ${# args[@]} ]]; do
29+ local arg=" ${args[$i]} "
30+ case " $arg " in
31+ build)
32+ # Skip the 'build' subcommand
33+ ;;
34+ --target)
35+ i=$(( i + 1 ))
36+ TARGET=" ${args[$i]} "
37+ ;;
38+ --target=* )
39+ TARGET=" ${arg# --target=} "
40+ ;;
41+ --profile)
42+ i=$(( i + 1 ))
43+ PROFILE=" ${args[$i]} "
44+ ;;
45+ --profile=* )
46+ PROFILE=" ${arg# --profile=} "
47+ ;;
48+ --features)
49+ i=$(( i + 1 ))
50+ if [[ -n " $FEATURES " ]]; then
51+ FEATURES=" $FEATURES ,${args[$i]} "
52+ else
53+ FEATURES=" ${args[$i]} "
54+ fi
55+ ;;
56+ --features=* )
57+ local feat=" ${arg# --features=} "
58+ if [[ -n " $FEATURES " ]]; then
59+ FEATURES=" $FEATURES ,$feat "
60+ else
61+ FEATURES=" $feat "
62+ fi
63+ ;;
64+ --message-format=* )
65+ MESSAGE_FORMAT=" $arg "
66+ ;;
67+ * )
68+ OTHER_ARGS+=(" $arg " )
69+ ;;
70+ esac
71+ i=$(( i + 1 ))
72+ done
73+ }
74+
75+ parse_args
76+
77+ # Fallback to detecting target from rustc if not provided
78+ if [[ -z " $TARGET " ]]; then
79+ TARGET=$( rustc -Vv | grep host | cut -d' ' -f2)
80+ fi
81+
82+ # Default features if not provided
83+ if [[ -z " $FEATURES " ]]; then
84+ FEATURES=" cli,asm,mimalloc"
85+ fi
86+
87+ LLVM_VERSION=$( rustc -Vv | grep -oP ' LLVM version: \K\d+' || echo " " )
88+
89+ # Check if we can do PGO+BOLT (Linux x86_64 only for now)
90+ CAN_PGO_BOLT=false
91+ if [[ " $OSTYPE " == " linux-gnu" * ]] && [[ " $TARGET " == " x86_64-unknown-linux-gnu" ]]; then
92+ CAN_PGO_BOLT=true
93+ fi
94+
95+ echo " === Build ===" >&2
96+ echo " Target: $TARGET " >&2
97+ echo " Profile: $PROFILE " >&2
98+ echo " Features: $FEATURES " >&2
99+ echo " LLVM Version: $LLVM_VERSION " >&2
100+ echo " PGO+BOLT enabled: $CAN_PGO_BOLT " >&2
101+
8102CARGO_ARGS=(--profile " $PROFILE " --features " $FEATURES " )
9103
10- TARGET=$( rustc -Vv | grep host | cut -d' ' -f2)
11- LLVM_VERSION=$( rustc -Vv | grep -oP ' LLVM version: \K\d+' )
104+ # Fallback to regular cargo build for unsupported platforms
105+ if [[ " $CAN_PGO_BOLT " != " true" ]]; then
106+ echo " PGO+BOLT not supported on this platform, falling back to regular build" >&2
107+ # Run regular cargo build with JSON output directly to fd 3
108+ cargo build " ${CARGO_ARGS[@]} " --message-format=json-render-diagnostics >&3
109+ exit 0
110+ fi
12111
13112install_bolt () {
14113 if command -v llvm-bolt & > /dev/null; then
114+ echo " BOLT already installed" >&2
15115 return
16116 fi
117+ echo " Installing BOLT from apt.llvm.org..." >&2
17118 wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc > /dev/null
18119 CODENAME=$( lsb_release -cs)
19120 echo " deb http://apt.llvm.org/$CODENAME / llvm-toolchain-$CODENAME -$LLVM_VERSION main" | sudo tee /etc/apt/sources.list.d/llvm.list > /dev/null
@@ -29,24 +130,49 @@ run() {
29130
30131export LLVM_PROFILE_FILE=$PWD /target/pgo-profiles/solar_%m_%p.profraw
31132
32- cargo install cargo-pgo
133+ echo " Installing cargo-pgo..." >&2
134+ cargo install cargo-pgo --quiet
33135rustup component add llvm-tools-preview
34136install_bolt
35137cargo pgo info
36138
37139readarray -t TESTDATA < <( find testdata -maxdepth 1 -name ' *.sol' ! -name ' Optimism.sol' )
140+ echo " Using ${# TESTDATA[@]} test files for profiling" >&2
38141
39142# PGO: build instrumented, run, gather profiles
143+ echo " === PGO Phase ===" >&2
144+ echo " Building PGO-instrumented binary..." >&2
40145cargo pgo build -- " ${CARGO_ARGS[@]} "
146+ echo " Running instrumented binary to gather profiles..." >&2
41147run " target/$TARGET /$PROFILE /solar"
42148
43149# BOLT: build instrumented with PGO, run, optimize
150+ echo " === BOLT Phase ===" >&2
151+ echo " Building BOLT-instrumented binary with PGO..." >&2
44152cargo pgo bolt build --with-pgo -- " ${CARGO_ARGS[@]} "
153+ echo " Running BOLT-instrumented binary..." >&2
45154run " target/$TARGET /$PROFILE /solar-bolt-instrumented"
155+ echo " Optimizing with BOLT..." >&2
46156cargo pgo bolt optimize --with-pgo -- " ${CARGO_ARGS[@]} "
47157
158+ # Copy optimized binary to expected locations
159+ OPTIMIZED_BIN=" target/$TARGET /$PROFILE /solar-bolt-optimized"
48160for out in " target/$TARGET /$PROFILE " " target/$PROFILE " ; do
49161 mkdir -p " $out "
50- cp " target/ $TARGET / $PROFILE /solar-bolt-optimized " " $out /solar"
162+ cp " $OPTIMIZED_BIN " " $out /solar"
51163done
52- ls -lh " target/$PROFILE /solar"
164+
165+ echo " === Build Complete ===" >&2
166+ ls -lh " target/$PROFILE /solar" >&2
167+
168+ # Now produce JSON output for cargo-dist on stdout (fd 3 which was original stdout)
169+ # cargo-dist expects JSON messages from cargo build, we simulate a successful build
170+ # by outputting the artifact path in the expected format
171+ FINAL_BIN=" target/$TARGET /$PROFILE /solar"
172+ echo " Producing JSON output for cargo-dist..." >&2
173+
174+ # Output JSON message to original stdout for cargo-dist to parse
175+ cat >&3 << EOF
176+ {"reason":"compiler-artifact","package_id":"solar-compiler","manifest_path":"$PWD /crates/compiler/Cargo.toml","target":{"kind":["bin"],"crate_types":["bin"],"name":"solar","src_path":"$PWD /crates/compiler/src/main.rs","edition":"2021","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"3","debuginfo":0,"debug_assertions":false,"overflow_checks":false,"test":false},"features":["cli","asm","mimalloc"],"filenames":["$PWD /$FINAL_BIN "],"executable":"$PWD /$FINAL_BIN ","fresh":false}
177+ {"reason":"build-finished","success":true}
178+ EOF
0 commit comments