apollo_release.sh 4.9 KB
Newer Older
1
#! /usr/bin/env bash
2
set -e
3

4 5 6 7
TOP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
source "${TOP_DIR}/scripts/apollo.bashrc"

export OPT_APOLLO="$(dirname "${APOLLO_SYSROOT_DIR}")"
8
export PREFIX_DIR=/apollo/output
9 10 11 12 13 14 15 16 17

LIST_ONLY=0
RESOLVE_DEPS=0
PRE_CLEAN=0
BAZEL_OPTS="--config=opt --config=gpu"

function _usage() {
    info "Usage: $0 [Options]"
    info "Options:"
18
    info "${TAB} -p, --prefix <DIR> Use absolute path <DIR> as install prefix instead of '/apollo/output'"
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    info "${TAB} -l, --list         Print the list of installed files; don't install anything"
    info "${TAB} -c, --clean        Ensure clean install by removing prefix dir if exist before installing"
    info "${TAB} -r, --resolve      Also resolve APT packages on which this release build depends"
    info "${TAB} -h, --help         Show this message and exit"
}

function _check_arg_for_opt() {
    local opt="$1"
    local optarg="$2"
    if [[ -z "${optarg}" || "${optarg}" =~ ^-.* ]]; then
        error "Missing argument for ${opt}. Exiting..."
        exit 2
    fi
}

function parse_cmdline_args() {
    local prefix_dir=
    while [[ $# -gt 0 ]]; do
        local opt="$1"
        shift
        case "${opt}" in
            -p | --prefix)
                _check_arg_for_opt "${opt}" "$1"
                prefix_dir="$1"; shift
                ;;
            -l | --list)
                LIST_ONLY=1
                ;;
            -r | --resolve)
                RESOLVE_DEPS=1
                ;;
            -c | --clean)
                PRE_CLEAN=1
                ;;
            -h | --help)
                _usage
                exit 0
                ;;
            *)
                error "Unknown option: ${opt}"
                _usage
                exit 1
                ;;
        esac
    done
    if [[ "${RESOLVE_DEPS}" -gt 0 && "${LIST_ONLY}" -gt 0 ]]; then
        error "'-l,--list' and '-r,--resolve' cannot be used together"
        _usage
        exit 1
    fi
    if [[ "${prefix_dir}" = /* ]]; then
        PREFIX_DIR="${prefix_dir}"
    elif [[ -n "${prefix_dir}" ]]; then
        echo "Absolute prefix dir expected, got '${prefix_dir}'"
        exit 1
    fi
}
76

77 78
function retrieve_so_deps() {
    ldd $1 | awk '/=>/ {print $3}' | sort -u | \
79
        grep -Ev "^(${OPT_APOLLO}|/usr/local|${PREFIX_DIR})/"
80 81
}
export -f retrieve_so_deps
82

83 84
function generate_solibs() {
    listing="$1"
85
    find ${PREFIX_DIR}/bin ${APOLLO_SYSROOT_DIR}/bin -executable -type f  \
86 87
        -exec bash -c 'retrieve_so_deps "$0"' {}  \
            >> ${listing} \;
88
    find ${PREFIX_DIR}/lib ${PREFIX_DIR}/cyber ${PREFIX_DIR}/modules \
89 90 91 92 93 94 95
        -name "*.so" -exec bash -c 'retrieve_so_deps "$0"' {}  \
            >> ${listing} \;

    SYSLIB_DIRS=(
        /usr/local/fast-rtps/lib
        /usr/local/libtorch_cpu/lib
        /usr/local/libtorch_gpu/lib
96
        ${APOLLO_SYSROOT_DIR}/lib
97 98 99
    )

    for libdir in ${SYSLIB_DIRS[@]}; do
100
        find ${libdir} \( -type f -or -type l \) -name "*.so" \
101 102 103
            -exec bash -c 'retrieve_so_deps "$0"' {} \
                >> ${listing} \;
    done
104 105 106
    find /usr/local/qt5/ -name "*.so" -exec bash -c 'retrieve_so_deps "$0"' {}  \
            >> ${listing} \;

107 108 109 110 111
    cat ${listing} | sort -u
}

function solib_locate() {
    solib="$1"
112 113 114
    if [[ ${solib} != "/"* || ! -e ${solib} ]]; then
        return
    fi
115 116 117 118 119 120 121 122 123 124 125
    dest="$2"
    # https://superuser.com/questions/363444
    # /how-do-i-get-the-output-and-exit-value-of-a-subshell-when-using-bash-e
    if ! msg="$(dpkg -S ${solib} 2>/dev/null)" ; then
        echo "Warning: ${solib} doesn't seem to belong to any APT package."
    else
        result="$(echo "${msg}" | awk -F ': ' '{print $1}')"
        echo "${result}" >> ${dest}
    fi
}

126
PKGS_TXT="${PREFIX_DIR}/syspkgs.txt"
127 128 129 130 131 132 133 134 135 136 137 138
function generate_apt_pkgs() {
    sudo apt-get -y update
    listing="$(mktemp /tmp/syslibs.XXXXXX)"
    pkgs="$(mktemp /tmp/pkgs.XXXXXX)"
    for solib in $(generate_solibs "${listing}"); do
        solib_locate "${solib}" "${pkgs}"
    done
    sort -u ${pkgs} > ${PKGS_TXT}
    rm -f ${listing} ${pkgs}
}

function main() {
139
    parse_cmdline_args "$@"
140

141 142 143 144 145 146 147 148 149
    local install_opts=
    if [[ "${LIST_ONLY}" -gt 0 ]]; then
        install_opts="${install_opts} --list"
    fi
    if [[ "${PRE_CLEAN}" -gt 0 ]]; then
        install_opts="${install_opts} --pre_clean"
    fi
    bazel run ${BAZEL_OPTS} //:install \
        -- ${install_opts} "${PREFIX_DIR}"
150

151 152 153 154 155
    if [[ "${LIST_ONLY}" -gt 0 ]]; then
        return
    fi

    info "Resolve directory path for Apollo binary distribution..."
156
    find "${PREFIX_DIR}" \( -name "*.dag" -or -name "*.launch" \) -exec \
157
        sed -i 's@/apollo/bazel-bin@/apollo@g' {} \;
158 159
    find "${PREFIX_DIR}" -name "*.sh" -exec \
        sed -i 's@${TOP_DIR}/bazel-bin/modules@${TOP_DIR}/modules@g' {} \;
160 161 162 163 164 165
    ok "Done."
    if [[ "${RESOLVE_DEPS}" -gt 0 ]]; then
        info "Resolve runtime library dependencies and generate APT packages list..."
        generate_apt_pkgs
        ok "Done. Packages list has been writen to ${PKGS_TXT}"
    fi
166 167 168
}

main "$@"