diff --git a/scripts/dev_setup.sh b/scripts/dev_setup.sh index e6e90e1e3c..5ad7bf429b 100755 --- a/scripts/dev_setup.sh +++ b/scripts/dev_setup.sh @@ -1,7 +1,8 @@ #!/bin/bash # Copyright (c) The Diem Core Contributors +# Copyright (c) The Move Contributors # SPDX-License-Identifier: Apache-2.0 -# This script sets up the environment for the Diem build by installing necessary dependencies. +# This script sets up the environment for the Move build by installing necessary dependencies. # # Usage ./dev_setup.sh # v - verbose, print all statements @@ -14,28 +15,24 @@ # fast fail. set -eo pipefail -SCCACHE_VERSION=0.2.16-alpha.0 -#If installing sccache from a git repp set url@revision. -SCCACHE_GIT='https://github.com/diem/sccache.git@ef50d87a58260c30767520045e242ccdbdb965af' -GRCOV_VERSION=0.8.2 -GUPPY_GIT='https://github.com/facebookincubator/cargo-guppy@39ec940f36b0a0df96a330243d127cbe2db9f919' Z3_VERSION=4.8.13 CVC5_VERSION=0.0.3 DOTNET_VERSION=5.0 BOOGIE_VERSION=2.9.6 SOLC_VERSION="v0.8.11+commit.d7f03943" -SCRIPT_PATH="$( cd "$( dirname "$0" )" >/dev/null 2>&1 && pwd )" +SCRIPT_PATH="$(cd "$(dirname "$0")" >/dev/null 2>&1 && pwd)" cd "$SCRIPT_PATH/.." || exit function usage { echo "Usage:" - echo "Installs or updates necessary dev tools for diem/diem." - echo "-b batch mode, no user interactions and miminal output" + echo "Installs or updates necessary dev tools for Move." + echo "-b batch mode, no user interactions and minimal output" echo "-p update ${HOME}/.profile" echo "-t install build tools" echo "-y installs or updates Move prover tools: z3, cvc5, dotnet, boogie" echo "-d installs the solidity compiler" + echo "-g installs Git (required by the Move CLI)" echo "-v verbose mode" echo "-i installs an individual tool by name" echo "-n will target the /opt/ dir rather than the $HOME dir. /opt/bin/, /opt/rustup/, and /opt/dotnet/ rather than $HOME/bin/, $HOME/.rustup/, and $HOME/.dotnet/" @@ -45,13 +42,12 @@ function usage { function add_to_profile { eval "$1" - FOUND=$(grep -c "$1" < "${HOME}/.profile" || true) # grep error return would kill the script. + FOUND=$(grep -c "$1" <"${HOME}/.profile" || true) # grep error return would kill the script. if [ "$FOUND" == "0" ]; then - echo "$1" >> "${HOME}"/.profile + echo "$1" >>"${HOME}"/.profile fi } - # It is important to keep all path updates together to allow this script to work well when run in github actions # inside of a docker image created using this script. GHA wipes the home directory via docker mount options, so # this profile needs built and sourced on every execution of a job using the docker image. See the .github/actions/build-setup @@ -114,10 +110,10 @@ function install_rustup { echo installing rust. BATCH_MODE=$1 if [[ "$OPT_DIR" == "true" ]]; then - export RUSTUP_HOME=/opt/rustup/ - mkdir -p "$RUSTUP_HOME" || true - export CARGO_HOME=/opt/cargo/ - mkdir -p "$CARGO_HOME" || true + export RUSTUP_HOME=/opt/rustup/ + mkdir -p "$RUSTUP_HOME" || true + export CARGO_HOME=/opt/cargo/ + mkdir -p "$CARGO_HOME" || true fi # Install Rust @@ -126,11 +122,11 @@ function install_rustup { fi VERSION="$(rustup --version || true)" if [ -n "$VERSION" ]; then - if [[ "${BATCH_MODE}" == "false" ]]; then + if [[ "${BATCH_MODE}" == "false" ]]; then echo "Rustup is already installed, version: $VERSION" fi else - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable + curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable if [[ -n "${CARGO_HOME}" ]]; then PATH="${CARGO_HOME}/bin:${PATH}" else @@ -198,30 +194,11 @@ function install_openssl_dev { fi } -function install_lcov { - PACKAGE_MANAGER=$1 - #Differently named packages for lcov with different sources. - if [[ "$PACKAGE_MANAGER" == "apk" ]]; then - apk --update add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing lcov - fi - if [[ "$PACKAGE_MANAGER" == "apt-get" ]] || [[ "$PACKAGE_MANAGER" == "yum" ]] || [[ "$PACKAGE_MANAGER" == "dnf" ]] || [[ "$PACKAGE_MANAGER" == "brew" ]]; then - install_pkg lcov "$PACKAGE_MANAGER" - fi - if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then - echo nope no lcov for you. - echo You can try installing yourself with: - echo install_pkg git "$PACKAGE_MANAGER" - echo cd lcov; - echo git clone https://aur.archlinux.org/lcov.git - echo makepkg -si --noconfirm - fi -} - function install_tidy { PACKAGE_MANAGER=$1 #Differently named packages for tidy if [[ "$PACKAGE_MANAGER" == "apk" ]]; then - apk --update add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing tidyhtml + apk --update add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing tidyhtml else install_pkg tidy "$PACKAGE_MANAGER" fi @@ -243,7 +220,7 @@ function install_gcc_powerpc_linux_gnu { function install_toolchain { version=$1 - FOUND=$(rustup show | grep -c "$version" || true ) + FOUND=$(rustup show | grep -c "$version" || true) if [[ "$FOUND" == "0" ]]; then echo "Installing ${version} of rust toolchain" rustup install "$version" @@ -252,70 +229,43 @@ function install_toolchain { fi } -function install_sccache { - VERSION="$(sccache --version || true)" - if [[ "$VERSION" != "sccache ""${SCCACHE_VERSION}" ]]; then - if [[ -n "${SCCACHE_GIT}" ]]; then - git_repo=$( echo "$SCCACHE_GIT" | cut -d "@" -f 1 ); - git_hash=$( echo "$SCCACHE_GIT" | cut -d "@" -f 2 ); - cargo install sccache --git "$git_repo" --rev "$git_hash" --features s3 --locked - else - cargo install sccache --version="${SCCACHE_VERSION}" --features s3 --locked - fi - fi -} - -function install_cargo_guppy { - if ! command -v cargo-guppy &> /dev/null; then - git_repo=$( echo "$GUPPY_GIT" | cut -d "@" -f 1 ); - git_hash=$( echo "$GUPPY_GIT" | cut -d "@" -f 2 ); - cargo install cargo-guppy --git "$git_repo" --rev "$git_hash" --locked - fi -} - -function install_grcov { - if ! command -v grcov &> /dev/null; then - cargo install grcov --version="${GRCOV_VERSION}" --locked - fi -} - function install_dotnet { echo "Installing .Net" mkdir -p "${DOTNET_INSTALL_DIR}" || true if [[ $("${DOTNET_INSTALL_DIR}/dotnet" --list-sdks | grep -c "^${DOTNET_VERSION}" || true) == "0" ]]; then if [[ "$(uname)" == "Linux" ]]; then - # Install various prerequisites for .dotnet. There are known bugs - # in the dotnet installer to warn even if they are present. We try - # to install anyway based on the warnings the dotnet installer creates. - if [ "$PACKAGE_MANAGER" == "apk" ]; then - install_pkg icu "$PACKAGE_MANAGER" - install_pkg zlib "$PACKAGE_MANAGER" - install_pkg libintl "$PACKAGE_MANAGER" - install_pkg libcurl "$PACKAGE_MANAGER" - elif [ "$PACKAGE_MANAGER" == "apt-get" ]; then - install_pkg gettext "$PACKAGE_MANAGER" - install_pkg zlib1g "$PACKAGE_MANAGER" - elif [ "$PACKAGE_MANAGER" == "yum" ] || [ "$PACKAGE_MANAGER" == "dnf" ]; then - install_pkg icu "$PACKAGE_MANAGER" - install_pkg zlib "$PACKAGE_MANAGER" - elif [ "$PACKAGE_MANAGER" == "pacman" ]; then - install_pkg icu "$PACKAGE_MANAGER" - install_pkg zlib "$PACKAGE_MANAGER" - fi + # Install various prerequisites for .dotnet. There are known bugs + # in the dotnet installer to warn even if they are present. We try + # to install anyway based on the warnings the dotnet installer creates. + if [ "$PACKAGE_MANAGER" == "apk" ]; then + install_pkg icu "$PACKAGE_MANAGER" + install_pkg zlib "$PACKAGE_MANAGER" + install_pkg libintl "$PACKAGE_MANAGER" + install_pkg libcurl "$PACKAGE_MANAGER" + elif [ "$PACKAGE_MANAGER" == "apt-get" ]; then + install_pkg gettext "$PACKAGE_MANAGER" + install_pkg zlib1g "$PACKAGE_MANAGER" + elif [ "$PACKAGE_MANAGER" == "yum" ] || [ "$PACKAGE_MANAGER" == "dnf" ]; then + install_pkg icu "$PACKAGE_MANAGER" + install_pkg zlib "$PACKAGE_MANAGER" + elif [ "$PACKAGE_MANAGER" == "pacman" ]; then + install_pkg icu "$PACKAGE_MANAGER" + install_pkg zlib "$PACKAGE_MANAGER" + fi fi # Below we need to (a) set TERM variable because the .net installer expects it and it is not set # in some environments (b) use bash not sh because the installer uses bash features. if [[ "$(uname)" == "Darwin" ]]; then - # On Macs with M1 chip the dotnet-install.sh script will - # attempt to download the Arm64 version which does not exist - # for .NET 5.x so for now we have to force x64 version instead - # to work for both architectures (in emulation mode for the M1 - # chip). - curl -sSL https://dot.net/v1/dotnet-install.sh \ - | TERM=linux /bin/bash -s -- --channel $DOTNET_VERSION --install-dir "${DOTNET_INSTALL_DIR}" --version latest --architecture "x64" + # On Macs with M1 chip the dotnet-install.sh script will + # attempt to download the Arm64 version which does not exist + # for .NET 5.x so for now we have to force x64 version instead + # to work for both architectures (in emulation mode for the M1 + # chip). + curl -sSL https://dot.net/v1/dotnet-install.sh | + TERM=linux /bin/bash -s -- --channel $DOTNET_VERSION --install-dir "${DOTNET_INSTALL_DIR}" --version latest --architecture "x64" else - curl -sSL https://dot.net/v1/dotnet-install.sh \ - | TERM=linux /bin/bash -s -- --channel $DOTNET_VERSION --install-dir "${DOTNET_INSTALL_DIR}" --version latest + curl -sSL https://dot.net/v1/dotnet-install.sh | + TERM=linux /bin/bash -s -- --channel $DOTNET_VERSION --install-dir "${DOTNET_INSTALL_DIR}" --version latest fi else echo Dotnet already installed. @@ -329,6 +279,10 @@ function install_boogie { echo "Boogie $BOOGIE_VERSION already installed" else "${DOTNET_INSTALL_DIR}dotnet" tool update --tool-path "${DOTNET_INSTALL_DIR}tools/" Boogie --version $BOOGIE_VERSION + if [[ $? != 0 ]]; then + echo "failed to install boogie ${BOOGIE_VERSION}, if there is an more recent version installed, please consider uninstall it with" + echo "${DOTNET_INSTALL_DIR}dotnet tool uninstall --tool-path ${DOTNET_INSTALL_DIR}/tools Boogie" + fi fi } @@ -340,8 +294,8 @@ function install_z3 { echo "you may want to remove the shared instance to avoid version confusion" fi if command -v "${INSTALL_DIR}z3" &>/dev/null && [[ "$("${INSTALL_DIR}z3" --version || true)" =~ .*${Z3_VERSION}.* ]]; then - echo "Z3 ${Z3_VERSION} already installed" - return + echo "Z3 ${Z3_VERSION} already installed" + return fi if [[ "$(uname)" == "Linux" ]]; then Z3_PKG="z3-$Z3_VERSION-x64-glibc-2.28" @@ -356,7 +310,7 @@ function install_z3 { mkdir -p "$TMPFILE"/ ( cd "$TMPFILE" || exit - curl -LOs "https://github.com/junkil-park/z3/releases/download/z3-$Z3_VERSION/$Z3_PKG.zip" + curl -LO "https://github.com/junkil-park/z3/releases/download/z3-$Z3_VERSION/$Z3_PKG.zip" unzip -q "$Z3_PKG.zip" cp "$Z3_PKG/bin/z3" "${INSTALL_DIR}" chmod +x "${INSTALL_DIR}z3" @@ -372,8 +326,8 @@ function install_cvc5 { echo "you may want to remove the shared instance to avoid version confusion" fi if command -v "${INSTALL_DIR}cvc5" &>/dev/null && [[ "$("${INSTALL_DIR}cvc5" --version || true)" =~ .*${CVC5_VERSION}.* ]]; then - echo "cvc5 ${CVC5_VERSION} already installed" - return + echo "cvc5 ${CVC5_VERSION} already installed" + return fi if [[ "$(uname)" == "Linux" ]]; then CVC5_PKG="cvc5-Linux" @@ -396,13 +350,13 @@ function install_cvc5 { } function install_nodejs { - if [[ "$PACKAGE_MANAGER" == "apt-get" ]]; then - curl -fsSL https://deb.nodesource.com/setup_14.x | bash - - apt-get install -y nodejs - else - install_pkg nodejs "$PACKAGE_MANAGER" - fi - install_pkg npm "$PACKAGE_MANAGER" + if [[ "$PACKAGE_MANAGER" == "apt-get" ]]; then + curl -fsSL https://deb.nodesource.com/setup_14.x | "${PRE_COMMAND[@]}" bash - + "${PRE_COMMAND[@]}" apt-get install -y nodejs + else + install_pkg nodejs "$PACKAGE_MANAGER" + fi + install_pkg npm "$PACKAGE_MANAGER" } function install_solidity { @@ -421,7 +375,7 @@ function install_solidity { } function welcome_message { -cat < /dev/null; then - PACKAGE_MANAGER="yum" - elif command -v apt-get &> /dev/null; then - PACKAGE_MANAGER="apt-get" - elif command -v pacman &> /dev/null; then - PACKAGE_MANAGER="pacman" - elif command -v apk &>/dev/null; then - PACKAGE_MANAGER="apk" - elif command -v dnf &>/dev/null; then - echo "WARNING: dnf package manager support is experimental" - PACKAGE_MANAGER="dnf" - else - echo "Unable to find supported package manager (yum, apt-get, dnf, or pacman). Abort" - exit 1 - fi + # check for default package manager for linux + if [[ -f /etc/redhat-release ]]; then + # use yum by default + if command -v yum &>/dev/null; then + PACKAGE_MANAGER="yum" + elif command -v dnf &>/dev/null; then + # dnf is the updated default since Red Hat Enterprise Linux 8, CentOS 8, Fedora 22, and any distros based on these + echo "WARNING: dnf package manager support is experimental" + PACKAGE_MANAGER="dnf" + fi + elif [[ -f /etc/debian_version ]] && command -v apt-get &>/dev/null; then + PACKAGE_MANAGER="apt-get" + elif [[ -f /etc/arch-release ]] && command -v pacman &>/dev/null; then + PACKAGE_MANAGER="pacman" + elif [[ -f /etc/alpine-release ]] && command -v apk &>/dev/null; then + PACKAGE_MANAGER="apk" + fi + # if no default PACKAGE_MANAGER detected, pick one that's installed, this is usually useless + if [[ $PACKAGE_MANAGER == "" ]]; then + if command -v yum &>/dev/null; then + PACKAGE_MANAGER="yum" + elif command -v apt-get &>/dev/null; then + PACKAGE_MANAGER="apt-get" + elif command -v pacman &>/dev/null; then + PACKAGE_MANAGER="pacman" + elif command -v apk &>/dev/null; then + PACKAGE_MANAGER="apk" + elif command -v dnf &>/dev/null; then + echo "WARNING: dnf package manager support is experimental" + PACKAGE_MANAGER="dnf" + else + echo "Unable to find supported package manager (yum, apt-get, dnf, or pacman). Abort" + exit 1 + fi + fi elif [[ "$(uname)" == "Darwin" ]]; then - if command -v brew &>/dev/null; then - PACKAGE_MANAGER="brew" - else - echo "Missing package manager Homebrew (https://brew.sh/). Abort" - exit 1 - fi + if command -v brew &>/dev/null; then + PACKAGE_MANAGER="brew" + else + echo "Missing package manager Homebrew (https://brew.sh/). Abort" + exit 1 + fi else - echo "Unknown OS. Abort." - exit 1 + echo "Unknown OS. Abort." + exit 1 fi if [[ "$BATCH_MODE" == "false" ]]; then - welcome_message - printf "Proceed with installing necessary dependencies? (y/N) > " - read -e -r input - if [[ "$input" != "y"* ]]; then - echo "Exiting..." - exit 0 - fi + welcome_message + printf "Proceed with installing necessary dependencies? (y/N) > " + read -e -r input + if [[ "$input" != "y"* ]]; then + echo "Exiting..." + exit 0 + fi fi if [[ "$PACKAGE_MANAGER" == "apt-get" ]]; then - if [[ "$BATCH_MODE" == "false" ]]; then + if [[ "$BATCH_MODE" == "false" ]]; then echo "Updating apt-get......" fi - "${PRE_COMMAND[@]}" apt-get update + "${PRE_COMMAND[@]}" apt-get update if [[ "$BATCH_MODE" == "false" ]]; then - echo "Installing ca-certificates......" + echo "Installing ca-certificates......" fi - install_pkg ca-certificates "$PACKAGE_MANAGER" + install_pkg ca-certificates "$PACKAGE_MANAGER" fi if [[ "$INSTALL_PROFILE" == "true" ]]; then @@ -605,7 +587,6 @@ fi install_pkg curl "$PACKAGE_MANAGER" - if [[ "$INSTALL_BUILD_TOOLS" == "true" ]]; then install_build_essentials "$PACKAGE_MANAGER" install_pkg cmake "$PACKAGE_MANAGER" @@ -622,19 +603,13 @@ if [[ "$INSTALL_BUILD_TOOLS" == "true" ]]; then rustup component add rustfmt rustup component add clippy - install_cargo_guppy - install_sccache - install_grcov - install_pkg git "$PACKAGE_MANAGER" - install_lcov "$PACKAGE_MANAGER" install_nodejs "$PACKAGE_MANAGER" fi if [[ "$INSTALL_INDIVIDUAL" == "true" ]]; then - for (( i=0; i < ${#INSTALL_PACKAGES[@]}; i++ )); - do + for ((i = 0; i < ${#INSTALL_PACKAGES[@]}; i++)); do PACKAGE=${INSTALL_PACKAGES[$i]} - if ! command -v "install_${PACKAGE}" &> /dev/null; then + if ! command -v "install_${PACKAGE}" &>/dev/null; then install_pkg "$PACKAGE" "$PACKAGE_MANAGER" else "install_${PACKAGE}" @@ -659,8 +634,12 @@ if [[ "$INSTALL_SOLIDITY" == "true" ]]; then install_solidity fi +if [[ "$INSTALL_GIT" == "true" ]]; then + install_pkg git "$PACKAGE_MANAGER" +fi + if [[ "${BATCH_MODE}" == "false" ]]; then -cat <