| #!/bin/bash | |
| # Copyright 2020 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=Run, Inspect and Debug | |
| ### run a host tool produced by the build | |
| ## usage: fx host-tool [--no-build] TOOLNAME [TOOL_ARGS...] | |
| ## | |
| ## This looks for a tool named TOOLNAME in tool_paths.json and executes it | |
| ## with the provided TOOL_ARGS. | |
| ## --no-build does not attempt to build the tool if it does not exist | |
| ## --check-firewall print a warning if the tool isn't included in firewall | |
| ## rules. This is a no-op outside of macOS. | |
| ## --print print the tool path instead of executing it. TOOL_ARGS | |
| ## is ignored, but check-firewall and build behaves the | |
| ## same. | |
| ## | |
| ## If the tool is not known to the build system, for example if it is not in | |
| ## the GN build graph, a proper message will be printed and the script fails. | |
| ## This script is specially useful for other scripts, via fx-command-run, | |
| ## although it can also be used directly by final users. | |
| ## | |
| ## The tool will be built if host-tool is being run interactively, | |
| ## otherwise an error will be produced if the tool is missing. | |
| set -e | |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $? | |
| fx-config-read | |
| build=true | |
| print_only=false | |
| check_firewall=false | |
| function is_macos { | |
| [[ "$(uname -s)" == "Darwin" ]] | |
| } | |
| function firewall_cmd_macos { | |
| local fw | |
| if type -P "socketfilterfw"; then | |
| fw="socketfilterfw" | |
| else | |
| fw="/usr/libexec/ApplicationFirewall/socketfilterfw" | |
| fi | |
| "$fw" "$@" | |
| } | |
| function check_firewall_func { | |
| if is_macos; then | |
| if firewall_cmd_macos --getglobalstate | grep "disabled" > /dev/null; then | |
| return 0 | |
| fi | |
| if ! firewall_cmd_macos --getappblocked "$1" | grep "permitted" > /dev/null; then | |
| fx-warn "Firewall rules are not configured, you may need to run \"fx setup-macos\"" | |
| return 0 | |
| fi | |
| fi | |
| } | |
| while [[ $1 == --* ]]; do | |
| if [[ $1 == '--no-build' ]]; then | |
| build=false | |
| shift | |
| elif [[ $1 == '--print' ]]; then | |
| print_only=true | |
| shift | |
| elif [[ $1 == '--check-firewall' ]]; then | |
| check_firewall=true | |
| shift | |
| else | |
| fx-error "Unrecognized option: $1" | |
| fx-command-help | |
| exit 1 | |
| fi | |
| done | |
| if [[ $# -eq 0 || $1 == -* ]]; then | |
| fx-error "Invalid syntax" | |
| fx-command-help | |
| exit 1 | |
| fi | |
| toolname="$1" | |
| shift | |
| # list-build-artifacts fails with a reasonable error message if tool is unknown | |
| toolpath="$(fx-command-run list-build-artifacts --name "${toolname}" --expect-one tools)" | |
| if [[ ! -f "${FUCHSIA_BUILD_DIR}/${toolpath}" ]]; then | |
| # If the desire is to build, then it's important for the build to | |
| # have stdout and stderr to print to. There are two possible | |
| # conditions, one is that host-tool is being run with stdout going to | |
| # a terminal, the other is that stdout is being captured, for example | |
| # if the user is running `fx set-device`. In the latter case it is | |
| # desirable to attach the build to the controlling terminal, if there | |
| # is one. In the case where there is not, fall back to printing an | |
| # error, as if --no-build was passed. If stderr is also redirected, | |
| # then the build is cundontiionally skipped. | |
| if ! fx-is-stderr-tty; then | |
| build=false | |
| fi | |
| if ! $build; then | |
| fx-error "Tool \"${toolname}\" is required by this command and has not been built." | |
| fx-error "Please build it first: fx build ${toolpath}" | |
| exit 2 | |
| fi | |
| { | |
| echo "Building required tool \"${toolpath}\"..." | |
| fx-command-run build "${toolpath}" || exit $? | |
| } 1>&2 | |
| fi | |
| # Print a warning if the firewall doesn't allow this tool from running. | |
| if $check_firewall; then | |
| check_firewall_func "${FUCHSIA_BUILD_DIR}/${toolpath}" | |
| fi | |
| if $print_only; then | |
| echo "${FUCHSIA_BUILD_DIR}/${toolpath}" | |
| else | |
| exec "${FUCHSIA_BUILD_DIR}/${toolpath}" "$@" | |
| fi |