blob: b9c47e2931a18e17bad4f636cec8c8e3986be84b [file] [log] [blame]
set -eufo pipefail
# Save absolute script directory before cd'ing anywhere else, as $(dirname "$0")
# could be relative to the working directory.
readonly script_dir=$(cd "$(dirname "$0")" && pwd)
usage() {
cat <<EOS
Usage: $0 [-h]
This script prepares for a fidlbolt deployment. It:
1. Builds needed targets in \$FUCHSIA_DIR/out/fidlbolt.
This assumes you have fuchsia.git in the desired state. It will warn if there
are uncommitted changes or if the commit has not been merged on the remote.
2. Copies binaries and other files into ./deployment.
This uses the following directory structure:
./deployment/bin binaries (fidlc, fidl-format, etc.)
./deployment/lib shared libraries
./deployment/etc configuration files
./deployment/fuchsia parts of the fuchsia tree that have .fidl files
It preserves directories for FIDL libraries so that paths displayed in
fidlbolt (e.g. import tooltips) resemble Fuchsia source tree paths.
3. Writes ./deployment/etc/fidlbolt_deployment.json.
This includes hashes and timestamps for all the relevant repositories, and
version strings for other tools like clang-format and rustfmt.
After running the script, you can:
1. Run fidlbolt using the deployment: make run DEPLOYMENT=1
2. Build a Docker image: docker image build -t fidlbolt .
die() {
echo "$0: $*" >&2
exit 1
step() {
printf "\x1b[32;1m* %s\x1b[0m\n" "$*"
warn() {
printf "\x1b[31;1mWARNING:\x1b[0m %s\n" "$*" >&2
while getopts "h" opt; do
case $opt in
h) usage; exit 0 ;;
*) exit 1 ;;
shift $((OPTIND - 1))
if [[ $# -gt 0 ]]; then
die "unexpected arguments: $*"
if [[ -z "$FUCHSIA_DIR" ]]; then
die "FUCHSIA_DIR not set"
# Source to get the fx tool on the PATH.
# (Reset shell options before sourcing since does not expect them.)
set +ufo pipefail
source "$FUCHSIA_DIR/scripts/" || exit $?
source "$FUCHSIA_DIR/tools/devshell/lib/" || exit $?
set -ufo pipefail
# Unset this variable since we invalidate it below with `fx --dir`.
readonly binaries=(
readonly old_build_dir=$(< "$FUCHSIA_DIR/.fx-build-dir")
readonly rel_build_dir="out/fidlbolt"
readonly build_dir="$FUCHSIA_DIR/$rel_build_dir"
step "Building targets in $build_dir"
# Save the build status to prevent an early exit from `set -e` upon failure, so
# that we can restore the old build directory before exiting.
fx --dir "$rel_build_dir" set bringup.x64 --release || build_status=$?
fx build "${binaries[@]/#/host_x64/}" || build_status=$?
fx use "$old_build_dir"
[[ "$build_status" -ne 0 ]] && exit "$build_status"
step "Cleaning ./deployment"
cd "$script_dir"
rm -rf deployment/
mkdir -p deployment/{bin,lib,etc,fuchsia/{sdk/fidl,zircon}}
step "Copying binaries"
cp "${binaries[@]/#/$build_dir/host_x64/}" \
"$PREBUILT_CLANG_DIR/bin/clang-format" \
"$PREBUILT_RUST_DIR/bin/rustfmt" \
step "Copying shared libraries"
ldd "$PREBUILT_RUST_DIR/bin/rustfmt" \
| awk -v f="$FUCHSIA_DIR" 'substr($3, 1, length(f)) == f { print $3; }' \
| xargs -I% cp % deployment/lib
step "Copying FIDL libraries"
find "$FUCHSIA_DIR/sdk/fidl" -mindepth 1 -maxdepth 1 -type d -print0 \
| xargs -0 -I% cp -r % deployment/fuchsia/sdk/fidl
# TODO( Remove banjo.
find "$FUCHSIA_DIR/sdk/banjo" -mindepth 1 -maxdepth 1 -type d -print0 \
| xargs -0 -I% cp -r % deployment/fuchsia/sdk/banjo
cp -r "$FUCHSIA_DIR/zircon/vdso" deployment/fuchsia/zircon/vdso
# Remove the non-fidl files. This is easier and less error-prone than
# manipulating paths to call mkdir -p and only copying the .fidl files.
find deployment/fuchsia -type f -not -name '*.fidl' -delete
find deployment/fuchsia -type d -empty -delete
step "Copying etc files"
cp \
"$FUCHSIA_DIR/rustfmt.toml" \
hash() {
# Check for uncommitted changes
git update-index --refresh > /dev/null 2>&1
if ! git diff-index --quiet HEAD --; then
warn "fidlbolt_deployment.json is inaccurate due to uncommitted changes"
warn "$(pwd): uncommitted changes:"
git status -s -uno >&2
if [[ -z "$(git branch -r --contains HEAD)" ]]; then
warn "fidlbolt will have broken links due to unpublished commits"
warn "$(pwd): HEAD has not been published:"
git log HEAD -n1 --oneline >&2
git rev-parse --verify HEAD
timestamp() {
git show -s --format=%ct HEAD
# TODO( Get the exact commit for these tools.
readonly clang_format_version=$(
"$PREBUILT_CLANG_DIR/bin/clang-format" --version \
| awk 'NR==1{print $4;}'
readonly rustfmt_version=$(
"$PREBUILT_RUST_DIR/bin/rustfmt" --version \
| awk 'NR==1{sub(/-.*/, "", $2); print $2}'
step "Writing fidlbolt_deployment.json"
cat <<EOS > deployment/etc/fidlbolt_deployment.json
"fidlbolt": {
"hash": "$(hash)",
"timestamp": $(timestamp)
"fuchsia": {
"hash": "$(cd "$FUCHSIA_DIR" && hash)",
"timestamp": $(cd "$FUCHSIA_DIR" && timestamp)
"clang-format": {
"version": "$clang_format_version"
"rustfmt": {
"version": "$rustfmt_version"