Skip to content
Snippets Groups Projects
iop 14.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jonas Höglund's avatar
    Jonas Höglund committed
    #!/bin/bash
    
    arg=$1
    arr_index=0
    declare -a command_array
    declare -a help_array
    
    # Check if we should clone feeds with ssh or http
    developer=0
    
    which git >/dev/null && git remote -v 2>/dev/null | grep -qE '(git@|ssh://)' && developer=1
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    
    
    # Utility functions
    function register_command {
    
        command_array[$arr_index]=$1
        help_array[$arr_index]=$2
        arr_index=$((arr_index+1))
    }
    
    
    Piotr Kubik's avatar
    Piotr Kubik committed
    function dump_commands {
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        for i in $(seq 0 $arr_index); do
    
    Piotr Kubik's avatar
    Piotr Kubik committed
            output+=("${command_array[$i]}" "${help_array[$i]}")
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        done
    
    Piotr Kubik's avatar
    Piotr Kubik committed
        printf "Available commands:\n"
        printf "   %-25s%s\n" "${output[@]}" | sort
        printf "\n"
    
    # Parse yaml file, look for specified feed definition and create feeds.conf-like output
    function parse_yaml_feed() {
       local yaml_file="$1"
       local feed="$2"
       local yaml_content=$(cat "$yaml_file")
    
       # Extract the values
       local names=($(echo "$yaml_content" | grep -oP '(?<=name: ).*'))
       local urls=($(echo "$yaml_content" | grep -oP '(?<=uri: ).*'))
       local revisions=($(echo "$yaml_content" | grep -oP '(?<=revision: ).*'))
    
       # Create the output string
       local output=""
       for ((i=0; i<${#names[@]}; i++)); do
         if [ ${names[i]} == ${feed} ]; then
           output+="src-git-full ${names[i]} ${urls[i]}^${revisions[i]}\n"
         fi
       done
    
       echo -e "$output"
    }
    
    
    function has_profiles_feed() {
        # regex taken from ./scripts/feeds
        grep -qP '^src-([\w\-]+)((?:\s+--\w+(?:=\S+)?)*)\s+(profiles)' feeds.conf
    }
    
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    # Register bootstrap command that installs other commands from feeds
    
    function bootstrap() {
    
        cp feeds.conf.io feeds.conf
    
        parse_yaml_feed "profiles/include/iop_feed.yml" iopsys >> feeds.conf
    
        feeds=(iopsys)
        if has_profiles_feed; then
          feeds+=(profiles)
        fi
    
        if [ "$developer" == 1 ]; then
            ./scripts/feeds update -g "${feeds[@]}" || exit 1
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        else
    
            ./scripts/feeds update "${feeds[@]}" || exit 1
    
        ./scripts/feeds install -p iopsys iop || exit 1
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    }
    
    register_command "bootstrap" "Initial command to run to install other commands"
    
    function install_locales()
    {
        sudo locale-gen en_US.UTF-8
    }
    
    function install_pkgs()
    {
        local packages_misc="
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    bison
    build-essential
    ccache
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    curl
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    execstack
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    flex
    g++
    g++-multilib
    gawk
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    gettext
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    gtk-doc-tools
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    liblzo2-dev
    
    libncurses5
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    libncurses5-dev
    libssl-dev
    ncurses-term
    
    python3
    python3-cryptography
    
    python3-distutils
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    subversion
    svn-buildpackage
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    unzip
    uuid-dev
    wget
    zlib1g-dev
    
    cmake
    quilt
    
    Andreas Gnau's avatar
    Andreas Gnau committed
    cryptsetup
    
    libseccomp-dev
    libyajl-dev
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    "
        local packages_perl="libconvert-binary-c-perl libdigest-crc-perl"
    
        # do we need 32 bit compatibility libs ?
        if [ "$(uname -m | awk '{print$1}')" == "x86_64" ]; then
    	local packages_x64="libc6-dev-i386 lib32z1 libncurses5:i386"
        fi
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        # filter out already installed packages
    
    Suru Dissanaike's avatar
    Suru Dissanaike committed
        local packages_all="$packages_misc $packages_perl $packages_x64"
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        local needed=""
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        for pkg in $packages_all
        do
    	if ! dpkg -s $pkg >/dev/null 2>/dev/null
    	then
    	    needed="$needed $pkg"
    	fi
        done
    
        # install needed packages
        if [ -n "$needed" ]
        then
    	echo "Need to install dpkg packages [$needed]"
    	read -p "Do you approve installation of these packages (y/n): " ans
    	if [ "$ans" == "y" ]; then
    
    	    sudo apt-get update && sudo apt-get install $needed || exit $?
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    	else
    	    echo "can't continue. aborting!"
    	    exit 1
    	fi
        fi
    }
    
    check_bash()
    {
        local mysh=$(ls -hl /bin/sh | awk -F'[ ,/]' '{print$NF}')
        if [ "$mysh" != "bash" ]; then
    	echo "On Debian based systems, e.g. Ubuntu, /bin/sh must point to bash instead of $mysh"
    	read -p "Do you approve this change (y/n): " ans
    	if [ "$ans" == "y" ]; then
    	    sudo rm -f /bin/sh
    	    sudo ln -s bash /bin/sh
    	else
    	    echo "Warning! You haven't pointed /bin/sh to bash."
    	    exit 1
    	fi
        fi
    }
    
    
    download_check_hash() {
    
        local url="$1"
        local sha256="$2"
        local tarball="$(mktemp iop_brcm_tar.XXXXXXX)"
    
        wget -nv "$url" -O "$tarball" || return 1
        if ! sha256sum --quiet -c <(echo "${sha256} *${tarball}") >&2; then
            echo "Hash mismatch of tarball $url (expected: $sha256)" >&2
            sha256sum "$tarball" >&2
    
            return 1
        fi
        printf "%s" "$tarball"
    }
    
    download_extract_bcm() {
        local type="$1"
        local url="$2"
        local sha256="$3"
        local path="$4"
    
        local path_strip_no=0
    
        if [ ! -z "$5" ]; then
            path_strip_no="$5"
        fi
    
    
        local tarball="$(download_check_hash "$url" "$sha256")"
        if [ -z "$tarball" ]; then
            echo "Error: Error occurred during download or hash verification for $url"
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        fi
    
            # current 10.3/4.19/2.30/2.32 BCM toolchain has owner of files set to some employee who created the tar
    
            # Change to root during extraction
    
            sudo tar --owner=root --group=root -C "$path" --strip-components=$path_strip_no -Pxf "$tarball"
    
            ;;
        hnd_toolchain)
            sudo mkdir -p "$path" && \
    
            sudo tar --owner=root --group=root -C "$path" -xf "$tarball" --strip-components=1
    
            ;;
        wlan_fw_tools)
            (
            set -e
            sudo mkdir -p "$path"
            sudo unzip -j \
                "$tarball" \
                bcawlan-fw-build-post-process-tools/post-process-tools/\* \
                -d "$path/bin"
            sudo find "$path/bin" -type f -not -name '*.ini' -execdir chmod +x '{}' ';'
            )
            ;;
        *)
            echo "Error: Unknown type $type" >&2
            false
            ;;
        esac
        local ret=$?
    
        rm -f "$tarball"
    
    check_brcm_tools(){
        local install_arm=0
    
        local install_arm_softfp=0
        local install_arm_hf=0
    
        local install_aarch64=0
    
        local install_wlan_fw_tools=0
    
        local TOOLCHAIN_DIR="/opt/toolchains/"
    
        if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
    
            install_arm=1
            echo "Need to install Broadcom ARM toolchain"
    
        if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
            install_arm_softfp=1
            echo "Need to install Broadcom ARM-softfp toolchain"
        fi
    
        if [ ! -d ${TOOLCHAIN_DIR}crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
            install_arm_hf=1
            echo "Need to install Broadcom ARM-hf toolchain"
        fi
    
        if [ ! -d ${TOOLCHAIN_DIR}crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
    
            install_aarch64=1
            echo "Need to install Broadcom aarch64 toolchain"
        fi
    
        if [ ! -d /opt/bcawlan-fw-build-post-process-tools ]; then
            install_wlan_fw_tools=1
            echo "Need to install bcawlan-fw-build-post-process-tools"
        fi
    
    
        if [ "$install_arm" -eq 1 \
            -o "$install_arm_softfp" -eq 1 \
            -o "$install_arm_hf" -eq 1 \
            -o "$install_aarch64" -eq 1 \
    
            -o "$install_wlan_fw_tools" -eq 1 ]; then
    
            read -p "Do you approve installation of the aforementioned missing toolchains and tools (y/n): " ans
    
            if [ "$ans" == "y" ]; then
    
                echo "Downloading toolchain/tools"
    
            else
                echo "can't continue. aborting"
                exit 1
            fi
    
            # create install dir
    
            sudo mkdir -p ${TOOLCHAIN_DIR}
    
    
            if [ $install_arm -eq 1 ]; then
                echo "Installing ARM toolchain"
    
                download_extract_bcm \
                    toolchain \
    
                    https://download.iopsys.eu/iopsys/toolchain/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
                    38657d72a7726db3e13621784d3e1ad65e2721c0538e87cc38cf3266bde26d6f \
                    ${TOOLCHAIN_DIR}
            fi
            if [ $install_arm_softfp -eq 1 ]; then
                download_extract_bcm \
                    toolchain \
                    https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
                    9af29bac2ba6cbe51ee09467dbe97dc76a47bbf00df1fffafa1433817d2a147b \
                    ${TOOLCHAIN_DIR}
            fi
            if [ $install_arm_hf -eq 1 ]; then
                download_extract_bcm \
                    toolchain \
                    https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
                    3e57bbbb5e0b832813aa93274dfa937260833af645c2bc03cb1c88d4e98def92 \
                    ${TOOLCHAIN_DIR}
    
            fi
            if [ $install_aarch64 -eq 1 ]; then
                echo "Installing aarch64 toolchain"
    
                download_extract_bcm \
                    toolchain \
    
                    https://download.iopsys.eu/iopsys/toolchain/crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
                    aed8c327951a5a7bfd67f9d2e92f844923a216994764e0aa32903bd40ea8945a \
                    ${TOOLCHAIN_DIR}
    
            if [ $install_wlan_fw_tools -eq 1 ]; then
                echo "Installing bcawlan-fw-build-post-process-tools"
                download_extract_bcm \
                    wlan_fw_tools \
                    https://download.iopsys.eu/iopsys/toolchain/bcawlan-fw-build-post-process-tools.zip \
                    1082d631317aef900ab2bfe549830bfbc76da87f21ff78cd3129f369f3f92101 \
                    /opt/bcawlan-fw-build-post-process-tools
            fi
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    }
    
    check_gcc_version(){
    
        gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
    
        # if /usr/bin/gcc -> /etc/alternatives/cc
        if [ -L $gcc_ver ]; then
    	gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
        fi
    
        # transform gcc-* to just a number.
        gcc_ver=$(echo $gcc_ver | cut -d- -f2)
    
    Jonas Höglund's avatar
    Jonas Höglund committed
        if [ "$gcc_ver" != 4.8 ]; then
    	echo "Your current gcc version is $gcc_ver, but it must be changed to 4.8"
    	read -p "Do you approve this change (y/n): " ans
    	if [ "$ans" == "y" ]; then
    	    if ! dpkg -s gcc-4.8 >/dev/null 2>/dev/null ;then
    		sudo apt-get install gcc-4.8
    	    fi
    	    if ! dpkg -s g++-4.8 >/dev/null 2>/dev/null ;then
    		sudo apt-get install g++-4.8
    	    fi
    	    if ! dpkg -s gcc-4.8-multilib >/dev/null 2>/dev/null ;then
    		sudo apt-get install gcc-4.8-multilib
    	    fi
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    	    sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-4.8 100
    	    sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-$gcc_ver 90
    
    	    sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-4.8 100
    	    sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-$gcc_ver 90
    
    	    sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-4.8 100
    	    sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-$gcc_ver 90
    
    	    sudo update-alternatives --set c++ /usr/bin/g++-4.8
    	    sudo update-alternatives --set cc  /usr/bin/gcc-4.8
    	    sudo update-alternatives --set cpp /usr/bin/cpp-4.8
    	    sudo ln -s /etc/alternatives/cc /usr/bin/cc 
    
    	    echo "The deafult gcc version has now been changed from $gcc_ver to 4.8"
    	fi
        fi
    }
    
    restore_gcc() {
        if dpkg -s gcc-5 >/dev/null 2>/dev/null
        then
    	gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
    
    	# if /usr/bin/gcc -> /etc/alternatives/cc
    	if [ -L $gcc_ver ]; then
    	    gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
    	fi
    
    	# transform gcc-* to just a number.
    	gcc_ver=$(echo $gcc_ver | cut -d- -f2)
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    	# is 4.8 the default reset back to 5 
    	if [ "$gcc_ver" = "4.8" ]; then
    	    echo "Your current gcc version is $gcc_ver that is not the distro default. set it back to default ?"
    	    read -p "Do you approve this change (y/n): " ans
    	    if [ "$ans" == "y" ]; then
    		sudo update-alternatives --set c++ /usr/bin/g++-5
    		sudo update-alternatives --set cc  /usr/bin/gcc-5
    		sudo update-alternatives --set cpp /usr/bin/cpp-5
    
    		# force a reinstall of default version
    		# yes it needs to be done twice.
    		sudo apt-get install --reinstall gcc cpp g++
    		sudo apt-get install --reinstall gcc cpp g++
    	    fi
    	fi
        fi
    }
    
    # Compare modification date of two files
    # return 0 (true) if first file is older, 1 (false) otherwise
    is_older() {
        local target=$(stat -c %Y $1 2> /dev/null)
        local ref=$(stat -c %Y $2 2> /dev/null)
    
        [ -z "$target" -o -z "$ref" ] && return 1
        [ $target -lt $ref ] && return 0
        return 1
    }
    
    install_iop_completion() {
        local instloc=/usr/share/bash-completion/completions/iop
        local srcloc=./feeds/iopsys/iop/iop.completion
        local inst=0
    
        if [ ! -e $instloc ]; then
            echo "Bash completion for './iop' utility not found"
            inst=1
        elif is_older $instloc $srcloc ; then
            echo "Bash completion for './iop' utility is outdated"
            inst=1
        fi
    
        if [ $inst -eq 1 ]; then
            read -p "Install latest version to '$instloc' (y/n): " ans
            if [ "$ans" == "y" ]; then
                sudo cp $srcloc $instloc
                echo "Start a new shell to enable ./iop command completion!"
            fi
        fi
    }
    
    function setup_host {
    
        #===============#
        # Prerequisites #
        #===============#
    
        install_locales
        install_pkgs
        check_bash
        check_brcm_tools
        #check_gcc_version
        restore_gcc
        install_iop_completion
    
        echo ""
        echo ""
        echo "You have successfully installed and configred prerequisites to be able to build an iopsys firmware"
        echo ""
        echo ""
    }
    
    register_command "setup_host" "Install needed packets to host machine"
    
    
    
    # Plugin scripts call register command to export their interface
    if [ -d package/feeds/iopsys/iop/scripts ]; then
    
        for f in package/feeds/iopsys/iop/scripts/*; do
    	source $f
        done
    fi
    
    
    function feeds_update {
    
        # Call bootstrap to update feeds/iopsys for transiton in old/new genconfig state
        echo "Calling bootstrap to update required feeds"
        bootstrap
    
        # always return true
        exit 0
    }
    
    register_command "feeds_update" "Compatibility function only"
    
    function set-feed-rev() {
        ./scripts/set-feed-rev "$@"
    }
    
    register_command "set-feed-rev" "Update feeds revisions in feeds.conf.io and profiles"
    
    
    # Register commands from external files
    
    source ./scripts/genconfig_wrap.sh
    
    source ./scripts/iopupgrade.sh
    
    
    Jonas Höglund's avatar
    Jonas Höglund committed
    if [ -z $arg ] || [ $arg == "--help" ]; then
        printf "Usage: iop <command> [<args>]\n\n"
        dump_commands
        exit -1
    fi
    
    # Check all registered commands for a match
    for i in $(seq 0 $arr_index); do
    
        if [ $arg == "${command_array[$i]}" ]; then
            # Run the command and pass all args 
            # except for the first to it
            $arg "${@:2}"
            exit 0
        fi
    
    done
    
    
    # No registered command for the passed input arg
    printf "Error: no such command $arg\n\n"
    dump_commands
    exit -1