| #!/usr/bin/env bash |
| # SPDX-License-Identifier: GPL-2.0 |
| |
| # A handy tool to launch CVD with local build or remote build. |
| |
| # --- Configuration Constants --- |
| readonly ACLOUD_PREBUILT="prebuilts/asuite/acloud/linux-x86/acloud" |
| readonly OPT_SKIP_PRERUNCHECK='--skip-pre-run-check' |
| PRODUCT='aosp_cf_x86_64_only_phone' |
| readonly DEFAULT_GSI_PRODUCT='gsi_x86_64' # Assuming this for GSI builds |
| SKIP_BUILD=false |
| USE_RBE=false |
| GCOV=false |
| DEBUG=false |
| KASAN=false |
| EXTRA_OPTIONS=() |
| CF_KERNEL_REPO_ROOT="" |
| CF_KERNEL_VERSION="" |
| PLATFORM_REPO_ROOT="" |
| PLATFORM_VERSION="" |
| |
| readonly REQUIRED_COMMANDS=("adb" "grep" "basename" "dirname" "read" "realpath" "nproc" "bc") |
| |
| # --- Library Import --- |
| SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")" |
| SCRIPT_DIR="$( cd "$( dirname "${SCRIPT_PATH}" )" &> /dev/null && pwd -P)" |
| LIB_PATH="${SCRIPT_DIR}/common_lib.sh" |
| |
| if [[ ! -f "$LIB_PATH" ]]; then |
| # Cannot use log_error yet as library isn't sourced |
| echo "FATAL ERROR: Cannot find required library '$LIB_PATH'" >&2 |
| exit 1 |
| fi |
| |
| # Source the library. Check return code in case sourcing fails (e.g., missing dependency in lib) |
| if ! . "$LIB_PATH"; then |
| echo "FATAL ERROR: Failed to source library '$LIB_PATH'. Check common_lib.sh dependencies." >&2 |
| exit 1 |
| fi |
| |
| # --- Functions --- |
| function print_help() { |
| echo "Usage: $0 [OPTIONS]" |
| echo "" |
| echo "This script will build images and launch a Cuttlefish device." |
| echo "" |
| echo "Available options:" |
| echo " --use-rbe Enable Remote Build Execution to speed up large, non-google3 builds." |
| echo " Requires RBE service access; See go/build-fast for details." |
| echo " --skip-build Skip the image build step. Will build by default if in repo." |
| echo " --gcov Launch CVD with gcov enabled kernel" |
| echo " --debug Launch CVD with debug enabled kernel" |
| echo " --kasan Launch CVD with kasan enabled kernel" |
| echo " -pb <platform_build>, --platform-build=<platform_build>" |
| echo " The platform build path. Can be a local path or a remote build" |
| echo " as ab://<branch>/<build_target>/<build_id>." |
| echo " If not specified, it will use the platform build in the local" |
| echo " repo, or the default compatible platform build for the kernel." |
| echo " -sb <system_build>, --system-build=<system_build>" |
| echo " The system build path for GSI testing. Can be a local path or" |
| echo " remote build as ab://<branch>/<build_target>/<build_id>." |
| echo " If not specified, no system build will be used." |
| echo " -kb <kernel_build>, --kernel-build=<kernel_build>" |
| echo " The kernel build path. Can be a local path or a remote build" |
| echo " as ab://<branch>/<build_target>/<build_id>." |
| echo " If not specified, it will use the kernel in the local repo." |
| echo " --acloud-bin=<acloud_bin>" |
| echo " The alternative alcoud binary path." |
| echo " --cf-product=<product_type>" |
| echo " The alternative cuttlefish product type for local build." |
| echo " Will use default aosp_cf_x86_64_phone if not specified." |
| echo " --acloud-arg=<acloud_arg>" |
| echo " Additional acloud command arg. Can be repeated." |
| echo " For example --acloud-arg=--local-instance to launch a local cvd." |
| echo " -h, --help Display this help message and exit" |
| echo "" |
| echo "Examples:" |
| echo "$0" |
| echo "$0 --acloud-arg=--local-instance" |
| echo "$0 -pb ab://git_main/aosp_cf_x86_64_phone-userdebug/latest" |
| echo "$0 -pb ~/main/out/target/product/vsoc_x86_64/" |
| echo "$0 -kb ~/android-mainline/out/virtual_device_x86_64/" |
| echo "" |
| exit 0 |
| } |
| |
| # Logs an error message and exits with the specified code (default 1). |
| function fail_error() { |
| local message="$1" |
| local exit_code="${2:-1}" |
| # Pass frame offset 2 to log_error to point to the caller of fail_error |
| log_error "$message" "$exit_code" 2 |
| exit "$exit_code" |
| } |
| |
| function parse_args() { |
| while test $# -gt 0; do |
| case "$1" in |
| -h|--help) |
| print_help |
| ;; |
| --use-rbe) |
| USE_RBE=true |
| shift |
| ;; |
| --skip-build) |
| SKIP_BUILD=true |
| shift |
| ;; |
| -pb) |
| shift |
| if test $# -gt 0; then |
| PLATFORM_BUILD="$1" |
| else |
| fail_error "platform build is not specified" |
| fi |
| shift |
| ;; |
| --platform-build=*) |
| PLATFORM_BUILD="$(echo "$1" | sed -e "s/^[^=]*=//g")" |
| shift |
| ;; |
| -sb) |
| shift |
| if test $# -gt 0; then |
| SYSTEM_BUILD="$1" |
| else |
| fail_error "system build is not specified" |
| fi |
| shift |
| ;; |
| --system-build=*) |
| SYSTEM_BUILD="$(echo "$1" | sed -e "s/^[^=]*=//g")" |
| shift |
| ;; |
| -kb) |
| shift |
| if test $# -gt 0; then |
| KERNEL_BUILD="$1" |
| else |
| fail_error "kernel build path is not specified" |
| fi |
| shift |
| ;; |
| --kernel-build=*) |
| KERNEL_BUILD="$(echo "$1" | sed -e "s/^[^=]*=//g")" |
| shift |
| ;; |
| --acloud-arg=*) |
| EXTRA_OPTIONS+=("$(echo "$1" | sed -e "s/^[^=]*=//g")") # Use array append syntax |
| shift |
| ;; |
| --acloud-bin=*) |
| ACLOUD_BIN="$(echo "$1" | sed -e "s/^[^=]*=//g")" |
| shift |
| ;; |
| --cf-product=*) |
| PRODUCT="$(echo "$1" | sed -e "s/^[^=]*=//g")" |
| shift |
| ;; |
| --gcov) |
| GCOV=true |
| shift |
| ;; |
| --debug) |
| DEBUG=true |
| shift |
| ;; |
| --kasan) |
| KASAN=true |
| shift |
| ;; |
| *) |
| fail_error "Unsupported flag: $1" >&2 |
| ;; |
| esac |
| done |
| } |
| |
| function create_kernel_build_cmd() { |
| local cf_kernel_repo_root=$1 |
| local cf_kernel_version=$2 |
| |
| local regex="((?<=android-)mainline|(\K\d+\.\d+(?=-stable)))|((?:android)\K\d+)" |
| local android_version |
| android_version=$(grep -oP "$regex" <(echo "$cf_kernel_version")) |
| local build_cmd="" |
| if [ -f "$cf_kernel_repo_root/common-modules/virtual-device/BUILD.bazel" ]; then |
| # support android-mainline, android16, android15, android14, android13 |
| build_cmd+="tools/bazel run" |
| if [ "$GCOV" = true ]; then |
| build_cmd+=" --gcov" |
| fi |
| if [ "$DEBUG" = true ]; then |
| build_cmd+=" --debug" |
| fi |
| if [ "$KASAN" = true ]; then |
| build_cmd+=" --kasan" |
| fi |
| build_cmd+=" //common-modules/virtual-device:virtual_device_x86_64_dist" |
| elif [ -f "$cf_kernel_repo_root/build/build.sh" ]; then |
| if [[ "$android_version" == "12" ]]; then |
| build_cmd+="BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh" |
| build_cmd+=" && " |
| build_cmd+="BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh" |
| elif [[ "$android_version" == "11" ]] || [[ "$android_version" == "4.19" ]]; then |
| build_cmd+="BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh" |
| build_cmd+=" && " |
| build_cmd+="BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh" |
| else |
| echo "The Kernel build $cf_kernel_version is not yet supported" >&2 |
| return 1 |
| fi |
| else |
| echo "The Kernel build $cf_kernel_version is not yet supported" >&2 |
| return 1 |
| fi |
| |
| echo "$build_cmd" |
| } |
| |
| function create_kernel_build_path() { |
| local cf_kernel_version=$1 |
| |
| local regex="((?<=android-)mainline|(\K\d+\.\d+(?=-stable)))|((?:android)\K\d+)" |
| local android_version |
| android_version=$(grep -oP "$regex" <(echo "$cf_kernel_version")) |
| if [ "$android_version" = "mainline" ] || greater_than_or_equal_to "$android_version" "14"; then |
| # support android-mainline, android16, android15, android14 |
| echo "out/virtual_device_x86_64/dist" |
| elif greater_than_or_equal_to "$android_version" "11" || [[ "$android_version" == "4.19" ]]; then |
| # support android13, android12, android11, android-4.19-stable |
| echo "out/$cf_kernel_version/dist" |
| else |
| echo "The version of this kernel build $cf_kernel_version is not supported yet" >&2 |
| return 1 |
| fi |
| } |
| |
| function greater_than_or_equal_to() { |
| local num1="$1" |
| local num2="$2" |
| |
| # This regex matches strings formatted as floating-point or integer numbers |
| local num_regex="^[0]([\.][0-9]+)?$|^[1-9][0-9]*([\.][0-9]+)?$" |
| if [[ ! "$num1" =~ $num_regex ]] || [[ ! "$num2" =~ $num_regex ]]; then |
| log_warn "Invalid numeric input for comparison: '$num1', '$num2'" |
| return 1 |
| fi |
| |
| # Use bc for comparison |
| if [[ $(echo "$num1 >= $num2" | bc -l) -eq 1 ]]; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| # Checks if target_path is within root_directory |
| function is_path_in_root() { |
| local root_directory="$1" |
| local target_path="$2" |
| |
| # expand the path variable, for example: |
| # "~/Documents" becomes "/home/user/Documents" |
| root_directory=$(eval echo "$root_directory") |
| target_path=$(eval echo "$target_path") |
| |
| # remove the trailing slashes |
| root_directory=$(realpath -m "$root_directory") |
| target_path=$(realpath -m "$target_path") |
| |
| # handles the corner case, for example: |
| # $root_directory="/home/user/Doc", $target_path="/home/user/Documents/" |
| root_directory="${root_directory}/" |
| |
| if [[ "$target_path" = "$root_directory"* ]]; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| function find_repo() { |
| manifest_output=$(grep -e "superproject" -e "common-modules/virtual-device" -e "default revision" \ |
| .repo/manifests/default.xml) |
| case "$manifest_output" in |
| *platform/superproject*) |
| PLATFORM_REPO_ROOT="$PWD" |
| PLATFORM_VERSION=$(grep -oP 'platform/superproject.*revision="\K[^"]*' <(echo "$manifest_output")) |
| if [ -z "$PLATFORM_VERSION" ]; then |
| # on main branch, <superproject> tag doesn't have a 'revision' attribute |
| # try to extract the information from <default> tag |
| PLATFORM_VERSION=$(grep -oP 'default revision="(refs/tags/)?\K[^"]*' <(echo "$manifest_output")) |
| fi |
| if [ -z "$PLATFORM_VERSION" ]; then |
| fail_error "Could not find platform version information." |
| fi |
| log_info "PLATFORM_REPO_ROOT=$PLATFORM_REPO_ROOT, PLATFORM_VERSION=$PLATFORM_VERSION" |
| ;; |
| *kernel/superproject*) |
| if [[ "$manifest_output" == *common-modules/virtual-device* ]]; then |
| CF_KERNEL_REPO_ROOT="$PWD" |
| CF_KERNEL_VERSION=$(grep -e "common-modules/virtual-device" \ |
| .repo/manifests/default.xml | grep -oP 'revision="\K[^"]*') |
| log_info "CF_KERNEL_REPO_ROOT=$CF_KERNEL_REPO_ROOT, CF_KERNEL_VERSION=$CF_KERNEL_VERSION" |
| fi |
| ;; |
| *) |
| log_warn "Unexpected manifest output. Could not determine repository type." |
| ;; |
| esac |
| } |
| |
| # Rebuilds the platform images using 'm'. Assumes environment is already set (lunch). |
| # WARNING: Uses 'eval'. Consider refactoring if build command becomes complex. |
| function rebuild_platform() { |
| local build_env_vars="" |
| local make_cmd="m -j$(nproc)" # Use nproc for parallelism |
| |
| # Conditionally add USE_RBE=false if not enabled via flag |
| if [[ "$USE_RBE" == false ]]; then |
| build_env_vars="USE_RBE=false " |
| fi |
| |
| local full_build_cmd="${build_env_vars}${make_cmd}" |
| |
| log_warn "Flag --skip-build is not set. Rebuilding platform images at $PWD" |
| log_info "Executing build command: ${BOLD}${full_build_cmd}${END}" |
| |
| # Execute the build command |
| local build_output build_exit_code |
| # Using eval here is still risky. If possible, invoke 'm' directly after exporting vars. |
| if build_output=$(eval "$full_build_cmd" 2>&1); then |
| build_exit_code=0 |
| else |
| build_exit_code=$? |
| fi |
| |
| # Check build success and output image existence |
| if [[ $build_exit_code -eq 0 ]]; then |
| if [[ -f "${ANDROID_PRODUCT_OUT}/system.img" ]]; then |
| log_info "Platform build command succeeded." |
| # log_info "Build output:\n${build_output}" # Optional: show output on success |
| return 0 |
| else |
| fail_error "Platform build command succeeded, but required output '${ANDROID_PRODUCT_OUT}/system.img' not found." 1 |
| fi |
| else |
| fail_error "Platform build command failed (Exit Code $build_exit_code). Output:\n${build_output}" "$build_exit_code" |
| fi |
| } |
| |
| # Rebuilds the kernel images. Assumes running in the kernel repo root. |
| # WARNING: Uses 'eval'. Consider refactoring. |
| function rebuild_kernel() { |
| local kernel_repo_root="$1" |
| local kernel_version="$2" |
| |
| log_warn "Flag --skip-build is not set. Rebuilding kernel images at $PWD" |
| |
| local build_cmd build_output build_exit_code |
| |
| # Get the build command string |
| if ! build_cmd=$(create_kernel_build_cmd "$kernel_repo_root" "$kernel_version"); then |
| fail_error "Failed to determine kernel build command." 1 |
| fi |
| |
| log_info "Executing kernel build command: ${BOLD}${build_cmd}${END}" |
| |
| # Execute the build command |
| # Using eval here is risky. Refactor if build_cmd structure allows. |
| if build_output=$(eval "$build_cmd" 2>&1); then |
| build_exit_code=0 |
| else |
| build_exit_code=$? |
| fi |
| |
| if [[ $build_exit_code -eq 0 ]]; then |
| log_info "Kernel build command succeeded." |
| # log_info "Build output:\n${build_output}" # Optional |
| return 0 |
| else |
| fail_error "Kernel build command failed (Exit Code $build_exit_code). Output:\n${build_output}" "$build_exit_code" |
| fi |
| } |
| |
| # --- Main Script Logic --- |
| |
| # 1. Check Core Dependencies |
| log_info "Checking required commands..." |
| if ! check_commands_available "${REQUIRED_COMMANDS[@]}"; then |
| fail_error "One or more required commands are missing. Please install them and retry." 1 |
| fi |
| |
| # 2. Parse Arguments |
| log_info "Parsing command line arguments..." |
| parse_args "$@" |
| |
| # 3. Determine Repo Root and Type |
| log_info "Determining repository context..." |
| repository_path="$PWD" |
| if ! is_in_repo_workspace; then |
| log_warn "Current directory '$PWD' is not within an Android repo workspace." |
| repository_path="$SCRIPT_DIR" |
| fi |
| if ! go_to_repo_root "$repository_path"; then |
| fail_error "Failed to navigate to repo root from $PWD." 1 |
| else |
| find_repo |
| fi |
| |
| # 4. Handle Platform Build/Path |
| log_info "Processing platform build..." |
| if [[ -z "$PLATFORM_BUILD" && -n "$PLATFORM_REPO_ROOT" ]]; then |
| log_info "Platform build not specified, using detected local platform repo: ${platform_repo_root}" |
| PLATFORM_BUILD="$PLATFORM_REPO_ROOT" |
| fi |
| |
| if [[ -n "$PLATFORM_BUILD" && "$PLATFORM_BUILD" != ab://* ]]; then |
| log_info "Local platform build path specified: ${PLATFORM_BUILD}" |
| # Resolve the path |
| if ! PLATFORM_BUILD=$(realpath -- "$PLATFORM_BUILD" 2>/dev/null); then |
| fail_error "Invalid local platform build path: ${PLATFORM_BUILD}" 1 |
| fi |
| if [[ ! -d "$PLATFORM_BUILD" ]]; then |
| fail_error "Local platform build path does not exist or is not a directory: ${PLATFORM_BUILD}" 1 |
| fi |
| |
| cd "$PLATFORM_BUILD" || fail_error "Failed to cd to $PLATFORM_BUILD" |
| |
| if is_in_repo_workspace; then |
| go_to_repo_root "$PWD" |
| |
| # Set up build environment (lunch) |
| log_info "Setting up platform build environment for product: $PRODUCT" |
| if [ -z "${TARGET_PRODUCT}" ] || [[ "${TARGET_PRODUCT}" != "$PRODUCT" ]]; then |
| log_info "TARGET_PRODUCT ('${TARGET_PRODUCT:-}') is not set or doesn't match '$PRODUCT'. Running lunch..." |
| if ! set_platform_repo "$PRODUCT" "userdebug" "$PWD"; then ## Assumes 'userdebug' variant, might need flexibility? |
| fail_error "Failed to set platform build environment (lunch)." 1 |
| fi |
| else |
| log_info "Build environment already set for TARGET_PRODUCT=${TARGET_PRODUCT}." |
| fi |
| |
| if [[ "$SKIP_BUILD" == false ]]; then |
| rebuild_platform |
| else |
| log_info "--skip-build specified, skipping platform rebuild." |
| fi |
| # After potential build, set platform_build to the actual output directory |
| if [[ -n "${ANDROID_PRODUCT_OUT:-}" && -d "${ANDROID_PRODUCT_OUT}" ]]; then |
| log_info "Setting platform build path to lunch output: ${ANDROID_PRODUCT_OUT}" |
| PLATFORM_BUILD="${ANDROID_PRODUCT_OUT}" |
| else |
| fail_error "ANDROID_PRODUCT_OUT ('${ANDROID_PRODUCT_OUT:-}') is not set or not a directory after lunch/build attempt." 1 |
| fi |
| else |
| if [[ "$SKIP_BUILD" == false ]]; then |
| log_warn "Local platform build path provided ('${PLATFORM_BUILD}'). --skip-build was not used, but automatic rebuilding is only done when running from within the platform repo source directory." |
| else |
| log_info "Current path $PWD is not a valid Android platform repo, please ensure it contains the platform image." |
| fi |
| fi |
| fi |
| |
| # 5. Handle System Build/Path |
| if [ "$SKIP_BUILD" = false ] && [ -n "$SYSTEM_BUILD" ] && [[ "$SYSTEM_BUILD" != ab://* ]] \ |
| && [ -d "$SYSTEM_BUILD" ]; then |
| # Get GSI build |
| cd "$SYSTEM_BUILD" || fail_error "Failed to cd to $SYSTEM_BUILD" |
| SYSTEM_REPO_LIST_OUT=$(repo list 2>&1) |
| if [[ "$SYSTEM_REPO_LIST_OUT" != "error"* ]]; then |
| go_to_repo_root "$PWD" |
| if [ -z "${TARGET_PRODUCT}" ] || [[ "${TARGET_PRODUCT}" != "${DEFAULT_GSI_PRODUCT}" ]]; then |
| log_warn "Build target product '${TARGET_PRODUCT}' does not match expected '${DEFAULT_GSI_PRODUCT}'. Reset build environment." |
| set_platform_repo "${DEFAULT_GSI_PRODUCT}" |
| rebuild_platform |
| SYSTEM_BUILD="${ANDROID_PRODUCT_OUT}/system.img" |
| fi |
| fi |
| fi |
| |
| # 6. Handle Kernel Build/Path |
| if [[ -n "$KERNEL_BUILD" && "$KERNEL_BUILD" != ab://* ]]; then |
| log_info "Local kernel build path specified: ${KERNEL_BUILD}" |
| # Resolve the path |
| if ! KERNEL_BUILD=$(realpath -- "$KERNEL_BUILD" 2>/dev/null); then |
| fail_error "Invalid local kernel build path: ${KERNEL_BUILD}" 1 |
| fi |
| if [[ ! -d "$KERNEL_BUILD" ]]; then |
| fail_error "Local kernel build path does not exist or is not a directory: ${KERNEL_BUILD}" 1 |
| fi |
| |
| log_info "Changing directory to kernel build: ${KERNEL_BUILD}" |
| cd -- "$KERNEL_BUILD" || fail_error "Failed to cd into kernel build directory: ${KERNEL_BUILD}" 1 |
| |
| if is_in_repo_workspace; then |
| go_to_repo_root "$PWD" |
| target_kernel_repo_root="$PWD" |
| target_cf_kernel_version=$(grep -e "common-modules/virtual-device" \ |
| .repo/manifests/default.xml | grep -oP 'revision="\K[^"]*') |
| |
| log_info "target_kernel_repo_root=$target_kernel_repo_root, target_cf_kernel_version=$target_cf_kernel_version" |
| |
| # Rebuild if not skipped |
| if [[ "$SKIP_BUILD" == false ]]; then |
| rebuild_kernel "$target_kernel_repo_root" "$target_cf_kernel_version" # Assumes PWD is kernel root |
| else |
| log_info "--skip-build specified, skipping kernel rebuild." |
| fi |
| |
| # Determine the expected output path after potential build |
| kernel_out_path="" |
| if ! kernel_out_path=$(create_kernel_build_path "$target_cf_kernel_version"); then |
| fail_error "Failed to determine kernel build output path for version ${cf_kernel_version}." 1 |
| fi |
| full_kernel_path="${target_kernel_repo_root}/${kernel_out_path}" |
| |
| # Check if the expected output directory exists |
| if [[ -d "$full_kernel_path" ]]; then |
| log_info "Setting kernel build path to detected output: ${full_kernel_path}" |
| KERNEL_BUILD="$full_kernel_path" |
| else |
| err_msg="Expected kernel build output directory '${full_kernel_path}' not found." |
| if [[ "$SKIP_BUILD" == true ]]; then |
| err_msg+="Don't skip re-building the kernel image." |
| fi |
| fail_error "$err_msg" 1 |
| fi |
| else |
| if [[ "$SKIP_BUILD" == false ]]; then |
| log_warn "Local kernel build path provided ('${KERNEL_BUILD}'). --skip-build was not used, but automatic rebuilding is only done when running from within the kernel repo source directory." |
| else |
| log_info "Current path $PWD is not a valid Android repo, please ensure it contains the kernel image." |
| fi |
| fi |
| fi |
| |
| # 7. Find acloud Binary |
| if [ -z "$ACLOUD_BIN" ] || ! [ -x "$ACLOUD_BIN" ]; then |
| log_info "Acloud binary path not specified or is not executable(--acloud-bin). Searching..." |
| if ACLOUD_BIN=$(which acloud 2>&1); then |
| log_info "Use acloud binary from: ${ACLOUD_BIN}" |
| else |
| # Fallback to prebuilt location relative to a detected repo root |
| potential_prebuilt_path="" |
| if [ -n "${PLATFORM_REPO_ROOT}" ]; then |
| potential_prebuilt_path="${PLATFORM_REPO_ROOT}/${ACLOUD_PREBUILT}" |
| elif [ -n "${CF_KERNEL_REPO_ROOT}" ]; then |
| potential_prebuilt_path="${CF_KERNEL_REPO_ROOT}/${ACLOUD_PREBUILT}" |
| fi |
| |
| if [[ -n "$potential_prebuilt_path" && -x "$potential_prebuilt_path" ]]; then |
| log_info "Using prebuilt acloud from repository: ${potential_prebuilt_path}" |
| ACLOUD_BIN="$potential_prebuilt_path" |
| else |
| fail_error "Could not find 'acloud' in PATH and failed to locate a valid prebuilt acloud in detected repo roots (${platform_repo_root:-none}, ${cf_kernel_repo_root:-none}). Specify path using --acloud-bin." |
| fi |
| fi |
| fi |
| |
| |
| # Final check if the determined/specified acloud binary is executable |
| if [[ ! -x "$ACLOUD_BIN" ]]; then |
| fail_error "Acloud binary found or specified is not executable: ${ACLOUD_BIN}" |
| fi |
| log_info "Using acloud binary: ${BOLD}${ACLOUD_BIN}${END}" |
| |
| acloud_cli="$ACLOUD_BIN create" |
| EXTRA_OPTIONS+=("$OPT_SKIP_PRERUNCHECK") |
| |
| # Add in branch if not specified |
| # 8. Construct acloud Command Arguments |
| if [ -z "$PLATFORM_BUILD" ]; then |
| log_warn "Platform build was not specified, and could not be determined from local repo. Will use the latest git_main build." |
| acloud_cli+=' --branch git_main' |
| elif [[ "$PLATFORM_BUILD" == ab://* ]]; then |
| IFS='/' read -ra array <<< "$PLATFORM_BUILD" |
| acloud_cli+=" --branch ${array[2]}" |
| |
| # Check if array[3] exists before using it |
| if [ ${#array[@]} -ge 3 ] && [ -n "${array[3]}" ]; then |
| acloud_cli+=" --build-target ${array[3]}" |
| |
| # Check if array[4] exists and is not 'latest' before using it |
| if [ ${#array[@]} -ge 4 ] && [ -n "${array[4]}" ] && [ "${array[4]}" != 'latest' ]; then |
| acloud_cli+=" --build-id ${array[4]}" |
| fi |
| fi |
| else |
| acloud_cli+=" --local-image $PLATFORM_BUILD" |
| fi |
| |
| if [ -z "$KERNEL_BUILD" ]; then |
| log_warn "Flag --kernel-build is not set, will not launch Cuttlefish with different kernel." |
| elif [[ "$KERNEL_BUILD" == ab://* ]]; then |
| IFS='/' read -ra array <<< "$KERNEL_BUILD" |
| acloud_cli+=" --kernel-branch ${array[2]}" |
| |
| # Check if array[3] exists before using it |
| if [ ${#array[@]} -ge 3 ] && [ -n "${array[3]}" ]; then |
| acloud_cli+=" --kernel-build-target ${array[3]}" |
| |
| # Check if array[4] exists and is not 'latest' before using it |
| if [ ${#array[@]} -ge 4 ] && [ -n "${array[4]}" ] && [ "${array[4]}" != 'latest' ]; then |
| acloud_cli+=" --kernel-build-id ${array[4]}" |
| fi |
| fi |
| else |
| acloud_cli+=" --local-kernel-image $KERNEL_BUILD" |
| fi |
| |
| if [ -z "$SYSTEM_BUILD" ]; then |
| log_warn "System build is not specified, will not launch Cuttlefish with GSI mixed build." |
| elif [[ "$SYSTEM_BUILD" == ab://* ]]; then |
| IFS='/' read -ra array <<< "$SYSTEM_BUILD" |
| acloud_cli+=" --system-branch ${array[2]}" |
| |
| # Check if array[3] exists before using it |
| if [ ${#array[@]} -ge 3 ] && [ -n "${array[3]}" ]; then |
| acloud_cli+=" --system-build-target ${array[3]}" |
| |
| # Check if array[4] exists and is not 'latest' before using it |
| if [ ${#array[@]} -ge 4 ] && [ -n "${array[4]}" ] && [ "${array[4]}" != 'latest' ]; then |
| acloud_cli+=" --system-build-id ${array[4]}" |
| fi |
| fi |
| else |
| acloud_cli+=" --local-system-image $SYSTEM_BUILD" |
| fi |
| |
| # 9. Execute acloud Command |
| acloud_cli+=" ${EXTRA_OPTIONS[*]}" |
| log_info "Launch CVD with command: $acloud_cli" |
| eval "$acloud_cli" |