|  | #!/bin/bash | 
|  | # Copyright 2017 The Fuchsia Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | #### CATEGORY=Build | 
|  | ### Run Ninja to build Fuchsia | 
|  |  | 
|  | ## usage: fx build [--log FILENAME] [-SWITCH...] [zircon/TARGET | TARGET ...] | 
|  | ## | 
|  | ## This runs Ninja, usually twice: once for Zircon and once for Fuchsia. | 
|  | ## With no explicit targets, Zircon Ninja builds its default targets and | 
|  | ## then Fuchsia Ninja builds its default targets. | 
|  | ## | 
|  | ## For each `zircon/TARGET` argument, `TARGET` is passed to Zircon Ninja. | 
|  | ## For each other `TARGET` argument, `TARGET` is passed to Fuchsia Ninja. | 
|  | ## If all the target arguments are `zircon/TARGET`, Fuchsia Ninja is not run. | 
|  | ## | 
|  | ## optional arguments: | 
|  | ##   --log LOGFILE    Print debug information to LOGFILE. Please attach the | 
|  | ##                    resulting file when reporting bugs. | 
|  | ##   --no-zircon      Skip building zircon (ignoring any zircon targets that | 
|  | ##                    may have been passed). This is useful for efficiently | 
|  | ##                    building host-side targets that have no zircon | 
|  | ##                    dependencies. | 
|  | ## | 
|  | ## Other arguments are passed through to Ninja (same switches for both Zircon | 
|  | ## and Fuchsia). | 
|  | ## Run `fx build -h` to see Ninja argument details. | 
|  |  | 
|  | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $? | 
|  | fx-config-read | 
|  |  | 
|  | function main { | 
|  | local switches=() zircon_targets=() fuchsia_targets=() | 
|  | local log_file is_logging continue_on_error | 
|  | is_logging=false | 
|  | build_zircon=true | 
|  | continue_on_error=false | 
|  | while [[ $# -gt 0 ]]; do | 
|  | case "$1" in | 
|  | --log) | 
|  | if [[ $# -lt 2 ]]; then | 
|  | fx-command-help | 
|  | return 1 | 
|  | fi | 
|  | log_file="$2" | 
|  | if [[ -f "${log_file}" ]]; then | 
|  | fx-error "File \"${log_file}\" exists." | 
|  | return 1 | 
|  | fi | 
|  | # if ! touch "${log_file}"; then | 
|  | #   fx-error "Cannot create logfile \"${log_file}\"" | 
|  | #   return 1 | 
|  | # fi | 
|  | is_logging=true | 
|  | shift | 
|  | ;; | 
|  | --no-zircon) | 
|  | build_zircon=false | 
|  | ;; | 
|  | # These Ninja switches take an argument. | 
|  | -[Cfjkldtw]) | 
|  | switches+=("$1" "$2") | 
|  | if [[ "$1" = "-k" && "$2" -eq 0 ]]; then | 
|  | continue_on_error=true | 
|  | fi | 
|  | shift | 
|  | ;; | 
|  | -*) | 
|  | switches+=("$1") | 
|  | ;; | 
|  | zircon/*) | 
|  | zircon_targets+=("${1#zircon/}") | 
|  | ;; | 
|  | *) | 
|  | fuchsia_targets+=("$1") | 
|  | ;; | 
|  | esac | 
|  | shift | 
|  | done | 
|  |  | 
|  | if [[ "${is_logging}" = true ]]; then | 
|  | # log file header with relevant environment information | 
|  | { | 
|  | TIMESTAMP="$(date +%Y%m%d_%H%M%S)" | 
|  | echo "Build initiated at ${TIMESTAMP}" | 
|  | echo | 
|  | echo "------ GIT QUICK INFO ------" | 
|  | echo "$ git status" | 
|  | git --git-dir="${FUCHSIA_DIR}/.git" status | 
|  | echo | 
|  | echo "$ git rev-parse JIRI_HEAD" | 
|  | git --git-dir="${FUCHSIA_DIR}/.git" rev-parse JIRI_HEAD | 
|  | echo | 
|  | echo "------ CONTENTS OF args.gn ------" | 
|  | echo "$ cat ${FUCHSIA_BUILD_DIR}/args.gn" | 
|  | echo | 
|  | cat "${FUCHSIA_BUILD_DIR}/args.gn" | 
|  | echo | 
|  | } >> "${log_file}" 2>&1 | 
|  |  | 
|  | # tee stdout and stderr to log_file | 
|  | exec > >(tee -a "${log_file}") 2>&1 | 
|  | fi | 
|  |  | 
|  | # A change to any of these might mean things are now done differently enough | 
|  | # that ninja's automatic re-gen rule might not be triggered or might not work | 
|  | # properly if it is triggered.  So preemptively force a re-gen if that seems | 
|  | # like a plausible possibility. | 
|  | local -r landmines=("$PREBUILT_GN" | 
|  | "$FUCHSIA_DIR/tools/devshell/build" | 
|  | "$FUCHSIA_DIR/tools/devshell/lib/vars.sh" | 
|  | ) | 
|  | local mine | 
|  | for mine in "${landmines[@]}"; do | 
|  | if [[ "$mine" -nt "${ZIRCON_BUILDROOT}/build.ninja" || \ | 
|  | "$mine" -nt "${FUCHSIA_BUILD_DIR}/build.ninja" ]]; then | 
|  | if [[ "${is_logging}" = true ]]; then | 
|  | echo -e "\\n------ RUNNING gn gen ------" | 
|  | fi | 
|  | echo >&2 "Re-running gn gen first ($mine changed)" | 
|  | fx-gen || return | 
|  | break | 
|  | fi | 
|  | done | 
|  |  | 
|  | if [[ ! -d "$ZIRCON_BUILDROOT" ]]; then | 
|  | if [[ "${is_logging}" = true ]]; then | 
|  | echo -e "\\n------ RUNNING gn gen ------" | 
|  | fi | 
|  | echo >&2 "Re-running gn gen first (missing $ZIRCON_BUILDROOT)" | 
|  | fx-gen || return | 
|  | fi | 
|  |  | 
|  | # Build requested Zircon targets. | 
|  | # Add default if building any Fuchsia targets. | 
|  | if [[ ${#fuchsia_targets[@]} -ne 0 ]]; then | 
|  | zircon_targets+=(default) | 
|  | fi | 
|  | local status | 
|  |  | 
|  | if [[ "${is_logging}" = true ]]; then | 
|  | echo -e "\\n------ RUNNING ninja ------" | 
|  | fi | 
|  |  | 
|  | if $build_zircon ; then | 
|  | (fx-run-ninja "${is_logging}" "$PREBUILT_NINJA" -C "${ZIRCON_BUILDROOT}" \ | 
|  | "${switches[@]}" "${zircon_targets[@]}") | 
|  | status=$? | 
|  | if [[ "${status}" -ne 0 && "$continue_on_error" = false ]]; then | 
|  | exit-with-message | 
|  | fi | 
|  | fi | 
|  |  | 
|  | # If there were explicit Zircon targets and no other explicit targets, | 
|  | # the Zircon run was enough by itself.  Otherwise Zircon default is | 
|  | # a prerequisite for any Fuchsia target (including implicit default). | 
|  | if [[ ${#fuchsia_targets[@]} -ne 0 || ${#zircon_targets[@]} -eq 0 ]]; then | 
|  | if [[ "${status}" -ne 0 ]]; then | 
|  | fx-warn "Build outputs may be inconsistent and may remain so; a clean build is recommended." | 
|  | fi | 
|  | (fx-run-ninja "${is_logging}" "$PREBUILT_NINJA" -C "${FUCHSIA_BUILD_DIR}" \ | 
|  | "${switches[@]}" "${fuchsia_targets[@]}") | 
|  | fuchsia_status=$? | 
|  | if [[ "${status}" -eq 0 ]]; then | 
|  | status="${fuchsia_status}" | 
|  | fi | 
|  | fi | 
|  |  | 
|  | exit-with-message | 
|  | } | 
|  |  | 
|  | function exit-with-message { | 
|  | if [[ "${is_logging}" = true ]]; then | 
|  | fx-warn "Debug log saved to ${log_file}. Please attach this file when reporting a bug" | 
|  | elif [[ "${status}" -ne 0 ]]; then | 
|  | echo >&2 "Hint: run \`fx build\` with the option \`--log LOGFILE\` to generate a debug log if you are reporting a bug." | 
|  | fi | 
|  | exit "${status}" | 
|  | } | 
|  |  | 
|  | main "$@" |