Path: blob/master/Tools/environment_install/install-prereqs-ubuntu.sh
9692 views
#!/usr/bin/env bash1echo "---------- $0 start ----------"2set -e3set -x45if [ $EUID == 0 ]; then6echo "Please do not run this script as root; don't sudo it!"7exit 18fi910OPT="/opt"11# Ardupilot Tools12ARDUPILOT_TOOLS="Tools/autotest"1314ASSUME_YES=false15QUIET=false16sep="##############################################"1718OPTIND=1 # Reset in case getopts has been used previously in the shell.19while getopts "yq" opt; do20case "$opt" in21\?)22exit 123;;24y) ASSUME_YES=true25;;26q) QUIET=true27;;28esac29done3031APT_GET="sudo apt-get"32if $ASSUME_YES; then33APT_GET="$APT_GET --assume-yes"34fi35if $QUIET; then36APT_GET="$APT_GET -qq"37fi3839# update apt package list40$APT_GET update4142function package_is_installed() {43dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed"44}4546function heading() {47echo "$sep"48echo $*49echo "$sep"50}5152# Install lsb-release as it is needed to check Ubuntu version53if ! package_is_installed "lsb-release"; then54heading "Installing lsb-release"55$APT_GET install lsb-release56echo "Done!"57fi5859# Checking Ubuntu release to adapt software version to install60RELEASE_CODENAME=$(lsb_release -c -s)6162RELEASE_DISTRIBUTOR=$(lsb_release -i -s | tr '[:upper:]' '[:lower:]')63case ${RELEASE_DISTRIBUTOR} in64elementary)65case ${RELEASE_CODENAME} in66jolnir)67RELEASE_CODENAME='focal'68;;69esac70;;71linuxmint)72# translate Mint-codenames to Ubuntu-codenames based on https://www.linuxmint.com/download_all.php73case ${RELEASE_CODENAME} in74wilma | xia)75RELEASE_CODENAME='noble'76;;77vanessa | vera | victoria | virginia)78RELEASE_CODENAME='jammy'79;;80una | uma | ulyssa | ulyana)81RELEASE_CODENAME='focal'82;;83tricia | tina | tessa | tara)84RELEASE_CODENAME='bionic'85;;86elsie)87RELEASE_CODENAME='bullseye'88;;89*)90echo "Unable to map ${RELEASE_CODENAME} to an Ubuntu release. Please patch this script and submit a pull request, or report at https://github.com/ArduPilot/ardupilot/issues"91exit 192esac93;;94esac9596PYTHON_V="python3" # starting from ubuntu 20.04, python isn't symlink to default python interpreter97PIP=pip39899if [ ${RELEASE_CODENAME} == 'bionic' ] ||100[ ${RELEASE_CODENAME} == 'buster' ]; then101echo "ArduPilot no longer supports developing on this operating system that has reached end of standard support."102exit 1103elif [ ${RELEASE_CODENAME} == 'trixie' ]; then104SITLFML_VERSION="2.6"105SITLCFML_VERSION="2.6"106PYTHON_V="python3"107PIP=pip3108elif [ ${RELEASE_CODENAME} == 'bookworm' ]; then109SITLFML_VERSION="2.5"110SITLCFML_VERSION="2.5"111PYTHON_V="python3"112PIP=pip3113elif [ ${RELEASE_CODENAME} == 'focal' ]; then114SITLFML_VERSION="2.5"115SITLCFML_VERSION="2.5"116PYTHON_V="python3"117PIP=pip3118elif [ ${RELEASE_CODENAME} == 'jammy' ]; then119SITLFML_VERSION="2.5"120SITLCFML_VERSION="2.5"121PYTHON_V="python3"122PIP=pip3123elif [ ${RELEASE_CODENAME} == 'lunar' ]; then124SITLFML_VERSION="2.5"125SITLCFML_VERSION="2.5"126PYTHON_V="python3"127PIP=pip3128elif [ ${RELEASE_CODENAME} == 'mantic' ]; then129SITLFML_VERSION="2.5"130SITLCFML_VERSION="2.5"131PYTHON_V="python3"132PIP=pip3133elif [ ${RELEASE_CODENAME} == 'noble' ]; then134SITLFML_VERSION="2.6"135SITLCFML_VERSION="2.6"136PYTHON_V="python3"137PIP=pip3138elif [ ${RELEASE_CODENAME} == 'oracular' ]; then139SITLFML_VERSION="2.6"140SITLCFML_VERSION="2.6"141PYTHON_V="python3"142PIP=pip3143elif [ ${RELEASE_CODENAME} == 'plucky' ]; then144SITLFML_VERSION="2.6"145SITLCFML_VERSION="2.6"146PYTHON_V="python3"147PIP="python3 -m pip"148elif [ ${RELEASE_CODENAME} == 'questing' ]; then149SITLFML_VERSION="2.6"150SITLCFML_VERSION="2.6"151PYTHON_V="python3"152PIP="python3 -m pip"153elif [ ${RELEASE_CODENAME} == 'groovy' ] ||154[ ${RELEASE_CODENAME} == 'bullseye' ]; then155SITLFML_VERSION="2.5"156SITLCFML_VERSION="2.5"157PYTHON_V="python3"158PIP=pip3159else160# We assume APT based system, so let's try with apt-cache first.161SITLCFML_VERSION=$(apt-cache search -n '^libcsfml-audio' | cut -d" " -f1 | head -1 | grep -Eo '[+-]?[0-9]+([.][0-9]+)?')162SITLFML_VERSION=$(apt-cache search -n '^libsfml-audio' | cut -d" " -f1 | head -1 | grep -Eo '[+-]?[0-9]+([.][0-9]+)?')163# If we cannot retrieve the number with apt-cache, try a last time with dpkg-query164re='^[+-]?[0-9]+([.][0-9]+)?$'165if ! [[ $SITLCFML_VERSION =~ $re ]] || ! [[ $SITLFML_VERSION =~ $re ]] ; then166# Extract the floating point number that is the version of the libcsfml package.167SITLCFML_VERSION=$(dpkg-query --search libcsfml-audio | cut -d":" -f1 | grep libcsfml-audio | head -1 | grep -Eo '[+-]?[0-9]+([.][0-9]+)?')168# And same for libsfml-audio.169SITLFML_VERSION=$(dpkg-query --search libsfml-audio | cut -d":" -f1 | grep libsfml-audio | head -1 | grep -Eo '[+-]?[0-9]+([.][0-9]+)?')170fi171fi172173# Check whether the specific ARM pkg-config package is available or whether we should emulate the effect of installing it.174# Check if we need to manually install libtool-bin175ARM_PKG_CONFIG_NOT_PRESENT=0176if [ -z "$(apt-cache search -n '^pkg-config-arm-linux-gnueabihf')" ]; then177ARM_PKG_CONFIG_NOT_PRESENT=$(dpkg-query --search pkg-config-arm-linux-gnueabihf |& grep -c "dpkg-query:")178fi179if [ "$ARM_PKG_CONFIG_NOT_PRESENT" -eq 1 ]; then180INSTALL_PKG_CONFIG=""181# No need to install Ubuntu's pkg-config-arm-linux-gnueabihf, instead install the base pkg-config.182$APT_GET install pkg-config183if [ -f /usr/share/pkg-config-crosswrapper ]; then184# We are on non-Ubuntu so simulate effect of installing pkg-config-arm-linux-gnueabihf.185sudo ln -sf /usr/share/pkg-config-crosswrapper /usr/bin/arm-linux-gnueabihf-pkg-config186else187echo "Warning: unable to link to pkg-config-crosswrapper"188fi189else190# Package is available so install it later.191INSTALL_PKG_CONFIG="pkg-config-arm-linux-gnueabihf"192fi193194# Lists of packages to install195BASE_PKGS="build-essential ccache g++ gawk git make wget valgrind screen python3-pexpect astyle"196PYTHON_PKGS="future lxml pymavlink pyserial MAVProxy geocoder empy==3.3.4 ptyprocess dronecan"197PYTHON_PKGS="$PYTHON_PKGS flake8 junitparser wsproto tabulate"198199# add some Python packages required for commonly-used MAVProxy modules and hex file generation:200if [[ $SKIP_AP_EXT_ENV -ne 1 ]]; then201PYTHON_PKGS="$PYTHON_PKGS pygame intelhex"202fi203ARM_LINUX_PKGS="g++-arm-linux-gnueabihf $INSTALL_PKG_CONFIG"204# python-wxgtk packages are added to SITL_PKGS below205206if [ ${RELEASE_CODENAME} == 'trixie' ] ||207[ ${RELEASE_CODENAME} == 'bookworm' ] ||208[ ${RELEASE_CODENAME} == 'lunar' ] ||209[ ${RELEASE_CODENAME} == 'mantic' ] ||210[ ${RELEASE_CODENAME} == 'noble' ] ||211[ ${RELEASE_CODENAME} == 'oracular' ] ||212[ ${RELEASE_CODENAME} == 'plucky' ] ||213[ ${RELEASE_CODENAME} == 'questing' ] ||214false; then215# on Lunar (and presumably later releases), we install in venv, below216PYTHON_PKGS+=" numpy pyparsing psutil"217SITL_PKGS="python3-dev"218else219SITL_PKGS="libtool libxml2-dev libxslt1-dev ${PYTHON_V}-dev ${PYTHON_V}-pip ${PYTHON_V}-setuptools ${PYTHON_V}-numpy ${PYTHON_V}-pyparsing ${PYTHON_V}-psutil"220fi221222# add some packages required for commonly-used MAVProxy modules:223if [[ $SKIP_AP_GRAPHIC_ENV -ne 1 ]]; then224if [ ${RELEASE_CODENAME} == 'trixie' ] ||225[ ${RELEASE_CODENAME} == 'bookworm' ] ||226[ ${RELEASE_CODENAME} == 'lunar' ] ||227[ ${RELEASE_CODENAME} == 'mantic' ] ||228[ ${RELEASE_CODENAME} == 'noble' ] ||229[ ${RELEASE_CODENAME} == 'oracular' ] ||230[ ${RELEASE_CODENAME} == 'plucky' ] ||231[ ${RELEASE_CODENAME} == 'questing' ] ||232false; then233PYTHON_PKGS+=" matplotlib scipy opencv-python pyyaml"234SITL_PKGS+=" xterm xfonts-base libcsfml-dev libcsfml-audio${SITLCFML_VERSION} libcsfml-dev libcsfml-graphics${SITLCFML_VERSION} libcsfml-network${SITLCFML_VERSION} libcsfml-system${SITLCFML_VERSION} libcsfml-window${SITLCFML_VERSION} libsfml-audio${SITLFML_VERSION} libsfml-dev libsfml-graphics${SITLFML_VERSION} libsfml-network${SITLFML_VERSION} libsfml-system${SITLFML_VERSION} libsfml-window${SITLFML_VERSION}"235else236SITL_PKGS="$SITL_PKGS xterm xfonts-base ${PYTHON_V}-matplotlib ${PYTHON_V}-serial ${PYTHON_V}-scipy ${PYTHON_V}-opencv libcsfml-dev libcsfml-audio${SITLCFML_VERSION} libcsfml-dev libcsfml-graphics${SITLCFML_VERSION} libcsfml-network${SITLCFML_VERSION} libcsfml-system${SITLCFML_VERSION} libcsfml-window${SITLCFML_VERSION} libsfml-audio${SITLFML_VERSION} libsfml-dev libsfml-graphics${SITLFML_VERSION} libsfml-network${SITLFML_VERSION} libsfml-system${SITLFML_VERSION} libsfml-window${SITLFML_VERSION} ${PYTHON_V}-yaml"237fi238fi239if [[ $SKIP_AP_COV_ENV -ne 1 ]]; then240# Coverage utilities241COVERAGE_PKGS="lcov gcovr"242fi243244# ArduPilot official Toolchain for STM32 boards245function install_arm_none_eabi_toolchain() {246# GNU Tools for ARM Embedded Processors247# (see https://launchpad.net/gcc-arm-embedded/)248ARM_ROOT="gcc-arm-none-eabi-10-2020-q4-major"249case $(uname -m) in250x86_64)251if [ ! -d $OPT/$ARM_ROOT ]; then252(253cd $OPT254heading "Installing toolchain for STM32 Boards"255echo "Installing toolchain for STM32 Boards"256echo "Downloading from ArduPilot server"257sudo wget --progress=dot:giga https://firmware.ardupilot.org/Tools/STM32-tools/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2258echo "Installing..."259sudo chmod -R 777 gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2260sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2261echo "... Cleaning"262sudo rm gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2263)264fi265echo "Registering STM32 Toolchain for ccache"266sudo ln -s -f $CCACHE_PATH /usr/lib/ccache/arm-none-eabi-g++267sudo ln -s -f $CCACHE_PATH /usr/lib/ccache/arm-none-eabi-gcc268echo "Done!";;269270aarch64)271if [ ! -d $OPT/$ARM_ROOT ]; then272(273cd $OPT274heading "Installing toolchain for STM32 Boards"275echo "Installing toolchain for STM32 Boards"276echo "Downloading from ArduPilot server"277sudo wget --progress=dot:giga https://firmware.ardupilot.org/Tools/STM32-tools/gcc-arm-none-eabi-10-2020-q4-major-aarch64-linux.tar.bz2278echo "Installing..."279sudo chmod -R 777 gcc-arm-none-eabi-10-2020-q4-major-aarch64-linux.tar.bz2280sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-aarch64-linux.tar.bz2281echo "... Cleaning"282sudo rm gcc-arm-none-eabi-10-2020-q4-major-aarch64-linux.tar.bz2283)284fi285echo "Registering STM32 Toolchain for ccache"286sudo ln -s -f $CCACHE_PATH /usr/lib/ccache/arm-none-eabi-g++287sudo ln -s -f $CCACHE_PATH /usr/lib/ccache/arm-none-eabi-gcc288echo "Done!";;289esac290}291292function maybe_prompt_user() {293if $ASSUME_YES; then294return 0295else296read -p "$1"297if [[ $REPLY =~ ^[Yy]$ ]]; then298return 0299else300return 1301fi302fi303}304305heading "Add user to dialout group to allow managing serial ports"306sudo usermod -a -G dialout $USER307echo "Done!"308309# Add back python symlink to python interpreter on Ubuntu >= 20.04310if [ ${RELEASE_CODENAME} == 'focal' ];311then312BASE_PKGS+=" python-is-python3"313SITL_PKGS+=" libpython3-stdlib" # for argparse314elif [ ${RELEASE_CODENAME} == 'groovy' ] ||315[ ${RELEASE_CODENAME} == 'bullseye' ] ||316[ ${RELEASE_CODENAME} == 'jammy' ]; then317BASE_PKGS+=" python-is-python3"318SITL_PKGS+=" libpython3-stdlib" # for argparse319elif [ ${RELEASE_CODENAME} == 'trixie' ]; then320SITL_PKGS+=" libpython3-stdlib" # for argparse321elif [ ${RELEASE_CODENAME} == 'bookworm' ]; then322SITL_PKGS+=" libpython3-stdlib" # for argparse323elif [ ${RELEASE_CODENAME} == 'lunar' ]; then324SITL_PKGS+=" libpython3-stdlib" # for argparse325elif [ ${RELEASE_CODENAME} != 'mantic' ] &&326[ ${RELEASE_CODENAME} != 'noble' ] &&327[ ${RELEASE_CODENAME} != 'oracular' ] &&328[ ${RELEASE_CODENAME} != 'plucky' ] &&329[ ${RELEASE_CODENAME} != 'questing' ] &&330true; then331if apt-cache search python-argparse | grep argp; then332SITL_PKGS+=" python-argparse"333elif apt-cache search python3-argparse | grep argp; then334SITL_PKGS+=" python3-argparse"335fi336fi337338# Check for graphical package for MAVProxy339if [[ $SKIP_AP_GRAPHIC_ENV -ne 1 ]]; then340if [ ${RELEASE_CODENAME} == 'bullseye' ]; then341SITL_PKGS+=" libjpeg62-turbo-dev"342elif [ ${RELEASE_CODENAME} == 'groovy' ] ||343[ ${RELEASE_CODENAME} == 'focal' ]; then344SITL_PKGS+=" libjpeg8-dev"345elif [ ${RELEASE_CODENAME} == 'trixie' ]; then346SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "347elif [ ${RELEASE_CODENAME} == 'bookworm' ]; then348SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "349elif [ ${RELEASE_CODENAME} == 'lunar' ]; then350SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "351elif [ ${RELEASE_CODENAME} == 'mantic' ]; then352SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "353# see below354elif [ ${RELEASE_CODENAME} == 'noble' ]; then355SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "356# see below357elif [ ${RELEASE_CODENAME} == 'oracular' ]; then358SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "359# see below360elif [ ${RELEASE_CODENAME} == 'plucky' ]; then361SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "362# see below363elif [ ${RELEASE_CODENAME} == 'questing' ]; then364SITL_PKGS+=" libgtk-3-dev libwxgtk3.2-dev "365# see below366elif apt-cache search python-wxgtk3.0 | grep wx; then367SITL_PKGS+=" python-wxgtk3.0"368elif apt-cache search python3-wxgtk4.0 | grep wx; then369# see below370:371else372# we only support back to trusty:373SITL_PKGS+=" python-wxgtk2.8"374SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libjpeg8-dev libpng12-0 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame375fi376377if [ ${RELEASE_CODENAME} == 'trixie' ]; then378PYTHON_PKGS+=" opencv-python"379SITL_PKGS+=" python3-wxgtk4.0"380SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame381elif [ ${RELEASE_CODENAME} == 'bookworm' ]; then382PYTHON_PKGS+=" opencv-python"383SITL_PKGS+=" python3-wxgtk4.0"384SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame385elif [ ${RELEASE_CODENAME} == 'lunar' ]; then386PYTHON_PKGS+=" wxpython opencv-python"387SITL_PKGS+=" python3-wxgtk4.0"388SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame389elif [ ${RELEASE_CODENAME} == 'mantic' ] ||390[ ${RELEASE_CODENAME} == 'noble' ] ||391[ ${RELEASE_CODENAME} == 'oracular' ] ||392[ ${RELEASE_CODENAME} == 'plucky' ] ||393[ ${RELEASE_CODENAME} == 'questing' ] ||394false; then395PYTHON_PKGS+=" wxpython opencv-python"396SITL_PKGS+=" python3-wxgtk4.0"397SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame398elif [ ${RELEASE_CODENAME} == 'bullseye' ] ||399[ ${RELEASE_CODENAME} == 'groovy' ] ||400[ ${RELEASE_CODENAME} == 'focal' ] ||401[ ${RELEASE_CODENAME} == 'jammy' ]; then402SITL_PKGS+=" python3-wxgtk4.0"403SITL_PKGS+=" fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev" # for pygame404fi405fi406407# Check if we need to manually install realpath408RP=$(apt-cache search -n '^realpath$')409if [ -n "$RP" ]; then410BASE_PKGS+=" realpath"411fi412413# Check if we need to manually install libtool-bin414LBTBIN=$(apt-cache search -n '^libtool-bin')415if [ -n "$LBTBIN" ]; then416SITL_PKGS+=" libtool-bin"417fi418419SITL_PKGS+=" ppp"420421# Install all packages422$APT_GET install $BASE_PKGS $SITL_PKGS $PX4_PKGS $ARM_LINUX_PKGS $COVERAGE_PKGS423424if [[ $SKIP_AP_GRAPHIC_ENV -ne 1 ]]; then425# If xfonts-base was just installed, you need to rebuild the font information cache.426# https://discuss.ardupilot.org/t/using-the-gdb-window-on-a-high-dpi-display/128150/2427fc-cache428fi429430heading "Check if we are inside docker environment..."431IS_DOCKER=false432if [[ ${AP_DOCKER_BUILD:-0} -eq 1 ]] || [[ -f /.dockerenv ]] || grep -Eq '(lxc|docker)' /proc/1/cgroup ; then433IS_DOCKER=true434fi435echo "Done!"436437SHELL_LOGIN=".profile"438if $IS_DOCKER; then439echo "Inside docker, we add the tools path into .bashrc directly"440SHELL_LOGIN=".ardupilot_env"441echo "# ArduPilot env file. Need to be loaded by your Shell." > ~/$SHELL_LOGIN442fi443444SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"445ARDUPILOT_ROOT=$(realpath "$SCRIPT_DIR/../../")446447PIP_USER_ARGUMENT="--user"448449# create a Python venv on more recent releases:450PYTHON_VENV_PACKAGE=""451if [ ${RELEASE_CODENAME} == 'bookworm' ] ||452[ ${RELEASE_CODENAME} == 'lunar' ] ||453[ ${RELEASE_CODENAME} == 'mantic' ]; then454PYTHON_VENV_PACKAGE=python3.11-venv455elif [ ${RELEASE_CODENAME} == 'noble' ]; then456PYTHON_VENV_PACKAGE=python3.12-venv457elif [ ${RELEASE_CODENAME} == 'oracular' ]; then458PYTHON_VENV_PACKAGE=python3.12-venv459elif [ ${RELEASE_CODENAME} == 'trixie' ] ||460[ ${RELEASE_CODENAME} == 'plucky' ] ||461[ ${RELEASE_CODENAME} == 'questing' ] ||462false; then463PYTHON_VENV_PACKAGE=python3-venv464fi465466if [ -n "$PYTHON_VENV_PACKAGE" ]; then467$APT_GET install $PYTHON_VENV_PACKAGE468469# Check if venv already exists in ARDUPILOT_ROOT (check both venv-ardupilot and venv)470VENV_PATH=""471if [ -d "$ARDUPILOT_ROOT/venv-ardupilot" ]; then472VENV_PATH="$ARDUPILOT_ROOT/venv-ardupilot"473echo "Found existing venv at $VENV_PATH"474elif [ -d "$ARDUPILOT_ROOT/venv" ]; then475VENV_PATH="$ARDUPILOT_ROOT/venv"476echo "Found existing venv at $VENV_PATH"477elif [ -d "$ARDUPILOT_ROOT/.venv" ]; then478VENV_PATH="$ARDUPILOT_ROOT/.venv"479echo "Found existing venv at $VENV_PATH"480else481VENV_PATH="$HOME/venv-ardupilot"482echo "Creating new venv at $VENV_PATH"483python3 -m venv --system-site-packages "$VENV_PATH"484fi485486SOURCE_LINE="source $VENV_PATH/bin/activate"487488# activate it:489$SOURCE_LINE490PIP_USER_ARGUMENT=""491492if [[ -z "${DO_PYTHON_VENV_ENV}" ]] && maybe_prompt_user "Make ArduPilot venv default for python [N/y]?\nThis means that any terminal will open and load ArduPilot venv" ; then493DO_PYTHON_VENV_ENV=1494fi495496if [[ $DO_PYTHON_VENV_ENV -eq 1 ]]; then497echo $SOURCE_LINE >> ~/$SHELL_LOGIN498else499echo "Please use \`$SOURCE_LINE\` to activate the ArduPilot venv"500fi501fi502503# try update packaging, setuptools and wheel before installing pip package that may need compilation504SETUPTOOLS="setuptools"505if [ ${RELEASE_CODENAME} == 'focal' ]; then506SETUPTOOLS=setuptools==70.3.0507fi508$PIP install $PIP_USER_ARGUMENT -U pip packaging $SETUPTOOLS wheel509510if [ "$GITHUB_ACTIONS" == "true" ]; then511PIP_USER_ARGUMENT+=" --progress-bar off"512fi513514if [ ${RELEASE_CODENAME} == 'trixie' ] ||515[ ${RELEASE_CODENAME} == 'bookworm' ] ||516[ ${RELEASE_CODENAME} == 'lunar' ] ||517[ ${RELEASE_CODENAME} == 'mantic' ] ||518[ ${RELEASE_CODENAME} == 'noble' ] ||519[ ${RELEASE_CODENAME} == 'oracular' ] ||520[ ${RELEASE_CODENAME} == 'plucky' ] ||521[ ${RELEASE_CODENAME} == 'questing' ] ||522false; then523# must do this ahead of wxPython pip3 run :-/524$PIP install $PIP_USER_ARGUMENT -U attrdict3525fi526527# install Python packages one-at-a-time so it is clear which package528# is causing problems:529for PACKAGE in $PYTHON_PKGS; do530if [ "$PACKAGE" == "wxpython" ]; then531echo "##### $PACKAGE takes a *VERY* long time to install (~30 minutes). Be patient."532# Use wheel repository for specific supported Ubuntu releases only533case ${RELEASE_CODENAME} in534focal)535echo "##### Adding wxpython wheel repository for faster installation"536WXPYTHON_WHEEL_REPO="https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04"537time $PIP install $PIP_USER_ARGUMENT -U -f $WXPYTHON_WHEEL_REPO $PACKAGE538;;539jammy)540echo "##### Adding wxpython wheel repository for faster installation"541WXPYTHON_WHEEL_REPO="https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-22.04"542time $PIP install $PIP_USER_ARGUMENT -U -f $WXPYTHON_WHEEL_REPO $PACKAGE543;;544noble)545echo "##### Adding wxpython wheel repository for faster installation"546WXPYTHON_WHEEL_REPO="https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-24.04"547time $PIP install $PIP_USER_ARGUMENT -U -f $WXPYTHON_WHEEL_REPO $PACKAGE548;;549*)550echo "##### Installing wxpython from PyPI (no specific wheel repository for this release)"551time $PIP install $PIP_USER_ARGUMENT -U $PACKAGE552;;553esac554else555time $PIP install $PIP_USER_ARGUMENT -U $PACKAGE556fi557done558559# somehow Plucky really wants Pillow reinstalled or MAVProxy's map560# won't load (version mismatch between "Core" and "Pillow")561if [ ${RELEASE_CODENAME} == 'plucky' ] ||562${RELEASE_CODENAME} == 'questing' ] ||563false; then564$PIP install --force-reinstall pillow565fi566567if [[ -z "${DO_AP_STM_ENV}" ]] && maybe_prompt_user "Install ArduPilot STM32 toolchain [N/y]?" ; then568DO_AP_STM_ENV=1569fi570571heading "Removing modemmanager and brltty package that could conflict with firmware uploading"572if package_is_installed "modemmanager"; then573$APT_GET remove modemmanager574fi575if package_is_installed "brltty"; then576$APT_GET remove brltty577fi578echo "Done!"579580CCACHE_PATH=$(which ccache)581if [[ $DO_AP_STM_ENV -eq 1 ]]; then582install_arm_none_eabi_toolchain583fi584585heading "Adding ArduPilot Tools to environment"586587if [[ $DO_AP_STM_ENV -eq 1 ]]; then588exportline="export PATH=$OPT/$ARM_ROOT/bin:\$PATH";589grep -Fxq "$exportline" ~/$SHELL_LOGIN 2>/dev/null || {590if maybe_prompt_user "Add $OPT/$ARM_ROOT/bin to your PATH [N/y]?" ; then591echo "$exportline" >> ~/$SHELL_LOGIN592eval "$exportline"593else594echo "Skipping adding $OPT/$ARM_ROOT/bin to PATH."595fi596}597fi598599exportline2="export PATH=\"$ARDUPILOT_ROOT/$ARDUPILOT_TOOLS:\"\$PATH";600grep -Fxq "$exportline2" ~/$SHELL_LOGIN 2>/dev/null || {601if maybe_prompt_user "Add $ARDUPILOT_ROOT/$ARDUPILOT_TOOLS to your PATH [N/y]?" ; then602echo "$exportline2" >> ~/$SHELL_LOGIN603eval "$exportline2"604else605echo "Skipping adding $ARDUPILOT_ROOT/$ARDUPILOT_TOOLS to PATH."606fi607}608609if [[ $SKIP_AP_COMPLETION_ENV -ne 1 ]]; then610exportline3="source \"$ARDUPILOT_ROOT/Tools/completion/completion.bash\"";611grep -Fxq "$exportline3" ~/$SHELL_LOGIN 2>/dev/null || {612if maybe_prompt_user "Add ArduPilot Bash Completion to your bash shell [N/y]?" ; then613echo "$exportline3" >> ~/.bashrc614eval "$exportline3"615else616echo "Skipping adding ArduPilot Bash Completion."617fi618}619fi620621exportline4="export PATH=/usr/lib/ccache:\$PATH";622grep -Fxq "$exportline4" ~/$SHELL_LOGIN 2>/dev/null || {623if maybe_prompt_user "Append CCache to your PATH [N/y]?" ; then624echo "$exportline4" >> ~/$SHELL_LOGIN625eval "$exportline4"626else627echo "Skipping appending CCache to PATH."628fi629}630echo "Done!"631632if [[ $SKIP_AP_GIT_CHECK -ne 1 ]]; then633if [ -d ".git" ]; then634heading "Update git submodules"635cd "$ARDUPILOT_ROOT"636git submodule update --init --recursive637echo "Done!"638fi639fi640641if $IS_DOCKER; then642echo "Finalizing ArduPilot env for Docker"643echo "source ~/.ardupilot_env">> ~/.bashrc644fi645646echo "---------- $0 end ----------"647648649