blob: 319628cdf77c0114d820e83efc8062567cc15a39 [file] [log] [blame]
#!/bin/bash
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 .
EOS
}
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 ;;
esac
done
shift $((OPTIND - 1))
if [[ $# -gt 0 ]]; then
die "unexpected arguments: $*"
fi
if [[ -z "$FUCHSIA_DIR" ]]; then
die "FUCHSIA_DIR not set"
fi
# Source fx-env.sh to get the fx tool on the PATH.
# Source vars.sh for PREBUILT_RUST_DIR.
# (Reset shell options before sourcing since vars.sh does not expect them.)
set +ufo pipefail
source "$FUCHSIA_DIR/scripts/fx-env.sh" || exit $?
source "$FUCHSIA_DIR/tools/devshell/lib/vars.sh" || exit $?
fx-config-read
set -ufo pipefail
# Unset this vars.sh variable since we invalidate it below with `fx --dir`.
unset FUCHSIA_BUILD_DIR
readonly binaries=(
"fidl-format"
"fidl-lint"
"fidlc"
"fidlgen_cpp"
"fidlgen_go"
"fidlgen_hlcpp"
"fidlgen_rust"
)
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"
cd "$FUCHSIA_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.
build_status=0
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" \
deployment/bin
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(fxbug.dev/72629) 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" \
deployment/etc
hash() {
# Check for uncommitted changes https://stackoverflow.com/a/3879077
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
fi
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
fi
git rev-parse --verify HEAD
}
timestamp() {
git show -s --format=%ct HEAD
}
# TODO(fxbug.dev/70699): 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"
}
}
EOS