mirror of
https://dev.iopsys.eu/iopsys/iopsyswrt.git
synced 2025-12-20 00:52:33 +08:00
When running ./iop --help or ./iop, return 0 instead of 255. Running --help is and displaying it successfully is not an error. Displaying help on running without arguments can be considered intended behaviour not justifying any error code. Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
520 lines
14 KiB
Bash
Executable File
520 lines
14 KiB
Bash
Executable File
#!/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
|
|
|
|
|
|
# Utility functions
|
|
function register_command {
|
|
|
|
command_array[$arr_index]=$1
|
|
help_array[$arr_index]=$2
|
|
arr_index=$((arr_index+1))
|
|
}
|
|
|
|
|
|
function dump_commands {
|
|
for i in $(seq 0 $arr_index); do
|
|
output+=("${command_array[$i]}" "${help_array[$i]}")
|
|
done
|
|
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
|
|
}
|
|
|
|
# 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
|
|
else
|
|
./scripts/feeds update "${feeds[@]}" || exit 1
|
|
fi
|
|
|
|
./scripts/feeds install -p iopsys iop || exit 1
|
|
}
|
|
|
|
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="
|
|
bc
|
|
bison
|
|
build-essential
|
|
ccache
|
|
cpio
|
|
curl
|
|
device-tree-compiler
|
|
dialog
|
|
file
|
|
flex
|
|
g++
|
|
g++-multilib
|
|
gawk
|
|
gdisk
|
|
gettext
|
|
git
|
|
automake
|
|
gtk-doc-tools
|
|
jq
|
|
libelf-dev
|
|
liblzo2-dev
|
|
libncurses6
|
|
libncurses-dev
|
|
libssl-dev
|
|
ncurses-term
|
|
pv
|
|
python3
|
|
python3-cryptography
|
|
python3-setuptools
|
|
python3-jsonschema
|
|
rsync
|
|
subversion
|
|
svn-buildpackage
|
|
swig
|
|
unzip
|
|
uuid-dev
|
|
wget
|
|
zlib1g-dev
|
|
xxd
|
|
cmake
|
|
quilt
|
|
cryptsetup
|
|
libcap-dev
|
|
libseccomp-dev
|
|
libyajl-dev
|
|
coccinelle
|
|
e2fsprogs
|
|
"
|
|
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 libncurses6:i386"
|
|
fi
|
|
|
|
# filter out already installed packages
|
|
local packages_all="$packages_misc $packages_perl $packages_x64"
|
|
local needed=""
|
|
|
|
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 $?
|
|
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
|
|
rm -f $tarball
|
|
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"
|
|
exit 1
|
|
fi
|
|
|
|
case "$type" in
|
|
toolchain)
|
|
# 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"
|
|
return "$ret"
|
|
}
|
|
|
|
|
|
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"
|
|
fi
|
|
|
|
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}
|
|
fi
|
|
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
|
|
fi
|
|
}
|
|
|
|
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)
|
|
|
|
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
|
|
|
|
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)
|
|
|
|
# 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
|
|
|
|
if [ -z $arg ] || [ $arg == "--help" ]; then
|
|
printf "Usage: iop <command> [<args>]\n\n"
|
|
dump_commands
|
|
exit 0
|
|
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
|
|
fi
|
|
done
|
|
|
|
|
|
# No registered command for the passed input arg
|
|
printf "Error: no such command $arg\n\n"
|
|
dump_commands
|
|
exit 1
|