mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
Determine the subtarget for a given device using data generated from the OpenWrt build system instead of parsing the image makefiles directly. This provides correct results even when fancy tricks like includes inside the Makefiles are used, which is the case for an upcoming feature where additional devices can be defined in external feeds. Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
504 lines
14 KiB
Bash
Executable file
504 lines
14 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
function genconfig {
|
|
export CLEAN=0
|
|
export IMPORT=1
|
|
export SRCTREEOVERR=0
|
|
export FILEDIR="files/"
|
|
CURRENT_CONFIG_FILE=".current_config_file"
|
|
export CONFIGPATH="package/feeds/iopsys/iop"
|
|
CUSTPATH="customerconfigs"
|
|
export CUSTCONF="customerconfigs/customers"
|
|
export VERBOSE=0
|
|
export DEVELOPER=0
|
|
target="bogus"
|
|
target_config_path=""
|
|
brcmbca_feed="target/linux/feeds/brcmbca"
|
|
airoha_feed="target/linux/feeds/airoha"
|
|
x86_feed="target/linux/feeds/iopsys-x86"
|
|
armvirt_feed="target/linux/feeds/iopsys-armvirt"
|
|
mediatek_feed="target/linux/feeds/iopsys-mediatek"
|
|
qualcomm_ipq95xx_feed="target/linux/feeds/ipq95xx"
|
|
|
|
Red='\033[0;31m' # Red
|
|
Color_Off='\033[0m' # Text Reset
|
|
Yellow='\033[0;33m' # Yellow
|
|
|
|
function find_last {
|
|
egrep "^[ #]*${1}[ =]" $2 | tail -n1
|
|
}
|
|
|
|
function is_new {
|
|
for opt in $conf_warned
|
|
do
|
|
if [ "$opt" == "$1" ]
|
|
then
|
|
return 1
|
|
fi
|
|
done
|
|
# option not found return true
|
|
return 0
|
|
}
|
|
|
|
function verify_config {
|
|
IFS=$'\n'
|
|
org=$(<.genconfig.config)
|
|
unset IFS
|
|
local num
|
|
local conf_opt
|
|
local conf_org
|
|
local conf_new
|
|
|
|
#echo "lines to check $tot_lines"
|
|
num=0
|
|
for line in $org
|
|
do
|
|
conf_opt=$(echo $line | grep CONFIG_ | sed 's|.*\(CONFIG_[^ =]*\)[ =].*|\1|')
|
|
if [ -n "${conf_opt}" ]
|
|
then
|
|
conf_org=$(find_last ${conf_opt} .genconfig.config)
|
|
conf_new=$(find_last ${conf_opt} .config)
|
|
if [ "$conf_org" != "$conf_new" ]
|
|
then
|
|
if is_new $conf_opt
|
|
then
|
|
echo -e "config option [${Red}$conf_opt${Color_Off}] is not set correctly in .config"
|
|
echo -e "got value [${Yellow}$conf_new${Color_Off}] but wanted [${Yellow}$conf_org${Color_Off}]"
|
|
echo "This is a real problem somebody needs to investigate"
|
|
echo ""
|
|
conf_warned="$conf_warned $conf_opt"
|
|
fi
|
|
else
|
|
true
|
|
# for debug to see all options
|
|
#echo -e "wanted [$conf_org] got [$conf_new]"
|
|
fi
|
|
fi
|
|
num=$((num+1))
|
|
done
|
|
}
|
|
|
|
# Takes a board name and returns the target name in global var $target
|
|
set_target() {
|
|
local profile=$1
|
|
|
|
[ -n "$profile" ] || return
|
|
|
|
if [ -n "$TARGET" -a -d "./target/linux/feeds/$TARGET" ]; then
|
|
local targetpath="./target/linux/feeds/$TARGET"
|
|
local profiles=
|
|
local pfound=0
|
|
|
|
if [ -e "$targetpath/genconfig" ]; then
|
|
profiles=$(cd $targetpath; ./genconfig)
|
|
|
|
for p in $profiles; do
|
|
if [ $p == $profile ]; then
|
|
pfound=1
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ $pfound -eq 1 ]; then
|
|
target="$(echo $TARGET | tr '-' '_')"
|
|
target_config_path="$targetpath/config"
|
|
fi
|
|
|
|
return
|
|
fi
|
|
|
|
[ -e $brcmbca_feed/genconfig ] &&
|
|
brcmbca=$(cd $brcmbca_feed; ./genconfig)
|
|
[ -e $airoha_feed/genconfig ] &&
|
|
airoha=$(cd $airoha_feed; ./genconfig)
|
|
[ -e $x86_feed/genconfig ] &&
|
|
iopsys_x86=$(cd $x86_feed; ./genconfig)
|
|
[ -e $armvirt_feed/genconfig ] &&
|
|
iopsys_armvirt=$(cd $armvirt_feed; ./genconfig)
|
|
[ -e $mediatek_feed/genconfig ] &&
|
|
iopsys_mediatek=$(cd $mediatek_feed; ./genconfig)
|
|
[ -e $qualcomm_ipq95xx_feed/genconfig ] &&
|
|
ipq95xx=$(cd $qualcomm_ipq95xx_feed; ./genconfig)
|
|
|
|
if [ "$profile" == "LIST" ]; then
|
|
for list in brcmbca airoha iopsys_x86 iopsys_armvirt iopsys_mediatek ipq95xx; do
|
|
echo "$list based boards:"
|
|
for b in ${!list}; do
|
|
echo -e "\t$b"
|
|
done
|
|
done
|
|
return
|
|
fi
|
|
|
|
for p in $brcmbca; do
|
|
if [ $p == $profile ]; then
|
|
target="brcmbca"
|
|
target_config_path="$brcmbca_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
|
|
for p in $airoha; do
|
|
if [ $p == $profile ]; then
|
|
target="airoha"
|
|
target_config_path="$airoha_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
|
|
for p in $iopsys_x86; do
|
|
if [ $p == $profile ]; then
|
|
target="iopsys_x86"
|
|
target_config_path="$x86_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
|
|
for p in $iopsys_armvirt; do
|
|
if [ $p == $profile ]; then
|
|
target="iopsys_armvirt"
|
|
target_config_path="$armvirt_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
|
|
for p in $iopsys_mediatek; do
|
|
if [ $p == $profile ]; then
|
|
target="iopsys_mediatek"
|
|
target_config_path="$mediatek_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
|
|
for p in $ipq95xx; do
|
|
if [ $p == $profile ]; then
|
|
target="ipq95xx"
|
|
target_config_path="$qualcomm_ipq95xx_feed/config"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
git remote -v | grep -qE '(git@|ssh://)' && {
|
|
DEVELOPER=1
|
|
}
|
|
|
|
v() {
|
|
[ "$VERBOSE" -ge 1 ] && echo "$@"
|
|
}
|
|
|
|
usage() {
|
|
echo
|
|
echo 1>&2 "Usage: $0 [ OPTIONS ] < Board_Type > [ Customer [customer2 ]...]"
|
|
echo
|
|
echo -e " -c|--clean\t\tRemove all files under ./files and import from config "
|
|
echo -e " -v|--verbose\t\tVerbose"
|
|
echo -e " -n|--no-update\tDo NOT! Update customer config before applying"
|
|
echo -e " -t|--target\t\tExplicitly specify the linux target to build the board profile from"
|
|
echo -e " -s|--override\t\tEnable 'Package source tree override'"
|
|
echo -e " -S|--brcmsingle\tForce build of bcmkernel to use only one thread"
|
|
echo -e " -h|--help\t\tShow this message"
|
|
echo -e " -l|--list [customer]\tList all Customers or all boards for one customer"
|
|
echo -e " -a|--list-all\t\tList all Customers and their board types"
|
|
echo -e " -b|--boards\t\tList all board types"
|
|
echo
|
|
echo "Example ./iop genconfig eg400 OPERATORX"
|
|
echo "(if no customerconfig is chosen, iopsys config will be used)"
|
|
echo
|
|
exit 0
|
|
}
|
|
|
|
list_customers()
|
|
{
|
|
local ALL="$1"
|
|
local CUSTOMER="$2"
|
|
if [ "$CUSTOMER" -a -d "$CUSTCONF/$CUSTOMER" ]; then
|
|
local boards="$(ls -1 "$CUSTCONF/$CUSTOMER" | grep -v common)"
|
|
if [ "$boards" ]; then
|
|
echo "$CUSTOMER has following boards:"
|
|
for board in $boards; do
|
|
echo -e "\t$board"
|
|
done
|
|
else
|
|
echo "No boards found for $CUSTOMER"
|
|
fi
|
|
elif [ "$CUSTOMER" ]; then
|
|
echo "No customer called $CUSTOMER"
|
|
exit 1
|
|
elif [ -d $CUSTCONF ]; then
|
|
local customers="$(ls -1 $CUSTCONF)"
|
|
if [ "$customers" -a "$ALL" == 1 ]; then
|
|
for customer in $customers; do
|
|
echo $customer
|
|
local boards="$(ls -1 $CUSTCONF/$customer | grep -v common)"
|
|
if [ "$boards" ]; then
|
|
for board in $boards; do
|
|
echo -e "\t$board"
|
|
done
|
|
else
|
|
echo "has no boards"
|
|
fi
|
|
done
|
|
elif [ "$customers" ]; then
|
|
echo -e "$customers"
|
|
else
|
|
echo "no customers found"
|
|
fi
|
|
else
|
|
echo "No $CUSTCONF folder found"
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
|
|
generate_config()
|
|
{
|
|
DIFFFILE="$1"
|
|
MASTERFILE="$2"
|
|
while read p; do
|
|
v "$p"
|
|
sed -r -i "$p" $MASTERFILE
|
|
done < $DIFFFILE
|
|
}
|
|
|
|
setup_dirs()
|
|
{
|
|
git remote -v | grep -q http || {
|
|
CUSTBRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
|
if git ls-remote $CUSTREPO -q 2>/dev/null; then
|
|
if [ ! -d "$CUSTPATH" ]; then
|
|
echo "Cloning $CUSTBRANCH branch of $CUSTREPO"
|
|
git clone -b "$CUSTBRANCH" "$CUSTREPO" "$CUSTPATH" 2>/dev/null || {
|
|
DEFBRANCH="$(git remote show $CUSTREPO | grep 'HEAD branch' | cut -d' ' -f5)"
|
|
echo "$CUSTBRANCH branch is not found, cloning $DEFBRANCH branch of $CUSTREPO"
|
|
git clone "$CUSTREPO" "$CUSTPATH"
|
|
}
|
|
elif [ $IMPORT -eq 1 ]; then
|
|
cd $CUSTPATH
|
|
echo "Checking out $CUSTBRANCH branch in $CUSTPATH"
|
|
git checkout "$CUSTBRANCH" 2>/dev/null || {
|
|
DEFBRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | cut -d '/' -f4)"
|
|
echo "Checking out $CUSTBRANCH branch has failed, using $DEFBRANCH branch in $CUSTPATH"
|
|
}
|
|
v "git pull"
|
|
git pull
|
|
cd - >/dev/null #go back
|
|
fi
|
|
else
|
|
echo "You do not have access to $CUSTREPO"
|
|
fi
|
|
}
|
|
|
|
if [ ! -d "$FILEDIR" ]; then
|
|
mkdir -p $FILEDIR
|
|
elif [ -d "$FILEDIR" -a $CLEAN -eq 1 ]; then
|
|
v "rm -rf $FILEDIR*"
|
|
rm -rf $FILEDIR*
|
|
fi
|
|
}
|
|
|
|
get_subtarget_for_device() {
|
|
readonly target="$1"
|
|
readonly device="$2"
|
|
readonly targetinfo_file="tmp/info/.targetinfo-feeds_$target"
|
|
readonly target_profile_line="Target-Profile: DEVICE_$device"
|
|
# We want to know after which Target: $target/$subtarget line
|
|
# our $target_profile_line appears
|
|
# This is a crude way to "parse" the file using shell 🤯
|
|
# 1. grep for both lines with line number output
|
|
# 2. grep again to determine the device profile line that we looked for
|
|
# but output one context line before as well to determine corresponding subtarget line
|
|
# 4. Use head and sed to extract the subtarget
|
|
grep "^Target: $target/\|^$target_profile_line" "$targetinfo_file" \
|
|
| grep -E -B1 "^$target_profile_line" \
|
|
| head -n1 \
|
|
| sed -E "s|^Target: $target/||"
|
|
}
|
|
|
|
create_and_copy_files()
|
|
{
|
|
local BOARDTYPE=$1
|
|
shift
|
|
local CUSTOMERS=$@
|
|
|
|
# Validate seleced board and customers
|
|
set_target $BOARDTYPE
|
|
if [ $target == "bogus" ]; then
|
|
echo "Hardware profile does not exist"
|
|
exit 1
|
|
elif [ -n "$CUSTOMERS" ]; then
|
|
for CUSTOMER in $CUSTOMERS; do
|
|
if [ ! -d "$CUSTCONF/$CUSTOMER/" ]; then
|
|
echo "Customer profile for '$CUSTOMER' does not exist"
|
|
exit 1
|
|
elif [ ! -d "$CUSTCONF/$CUSTOMER/$BOARDTYPE/" ]; then
|
|
echo "'$BOARDTYPE' board profile does not exist for customer '$CUSTOMER'"
|
|
if [ -f "$CUSTCONF/$CUSTOMER/common/common.diff" ]; then
|
|
echo "Common profile configuration will be used"
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Generate base config
|
|
rm -f .config
|
|
v "Config $BOARDTYPE selected"
|
|
v "cp $CONFIGPATH/config .config"
|
|
cp $CONFIGPATH/config .config
|
|
|
|
if [ -f $target_config_path/config ]; then
|
|
cat $target_config_path/config >> .config
|
|
echo "" >> .config
|
|
fi
|
|
if [ -f $target_config_path/$BOARDTYPE/config ]; then
|
|
cat $target_config_path/$BOARDTYPE/config >> .config
|
|
echo "" >> .config
|
|
fi
|
|
|
|
# Special handling for targets which use TARGET_DEVICES
|
|
case "$target" in
|
|
airoha | iopsys_mediatek | brcmbca | ipq95xx)
|
|
# This assumes the device name to be unique within one target,
|
|
# which is a fair assumption to make.
|
|
local subtarget="$(get_subtarget_for_device "$target" "$BOARDTYPE")"
|
|
if [ -z "$subtarget" ]; then
|
|
echo "Error determining subtarget for $target / ${BOARDTYPE}"
|
|
return 1
|
|
fi
|
|
echo "CONFIG_TARGET_${target}=y" >> .config
|
|
echo "CONFIG_TARGET_${target}_${subtarget}=y" >> .config
|
|
echo "CONFIG_TARGET_DEVICE_${target}_${subtarget}_DEVICE_${BOARDTYPE}=y" >> .config
|
|
;;
|
|
*)
|
|
echo "CONFIG_TARGET_${target}=y" >> .config
|
|
echo "CONFIG_TARGET_${target}_${BOARDTYPE}=y" >> .config
|
|
;;
|
|
esac
|
|
|
|
echo "$CUSTOMERS $BOARDTYPE" > $CURRENT_CONFIG_FILE
|
|
|
|
# Add customerconfig diff if a customer is selected
|
|
if [ -n "$CUSTOMERS" ]; then
|
|
for CUSTOMER in $CUSTOMERS; do
|
|
if [ -d "$CUSTCONF/$CUSTOMER/common/fs" ]; then
|
|
v "cp -ar $CUSTCONF/$CUSTOMER/common/fs/* $FILEDIR"
|
|
cp -ar $CUSTCONF/$CUSTOMER/common/fs/* $FILEDIR
|
|
fi
|
|
if [ -d "$CUSTCONF/$CUSTOMER/$BOARDTYPE/fs" ]; then
|
|
v "cp -ar $CUSTCONF/$CUSTOMER/$BOARDTYPE/fs/* $FILEDIR"
|
|
cp -ar $CUSTCONF/$CUSTOMER/$BOARDTYPE/fs/* $FILEDIR
|
|
fi
|
|
if [ -e "$CUSTCONF/$CUSTOMER/common/common.diff" ]; then
|
|
v "Apply $CUSTCONF/$CUSTOMER/common/common.diff"
|
|
cat $CUSTCONF/$CUSTOMER/common/common.diff >> .config
|
|
echo "" >> .config
|
|
fi
|
|
if [ -e "$CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff" ]; then
|
|
v "Apply $CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff"
|
|
cat $CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff >> .config
|
|
echo "" >> .config
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Set target version
|
|
local git_version
|
|
if ! git_version="$(git describe --always --dirty --tags --match '[0-9].*.*' --match '[0-9][0-9].*.*')"; then
|
|
echo "ERROR: Failed getting version via git describe, exiting." >&2
|
|
return 1
|
|
fi
|
|
local version="${git_version,,}${CUSTOMERS:+-${CUSTOMERS// /}}"
|
|
local version_lower="${version,,}"
|
|
echo "CONFIG_TARGET_VERSION=\"${version_lower}\"" >> .config
|
|
echo "CONFIG_VERSION_CODE=\"${version_lower}\"" >> .config
|
|
echo "CONFIG_VERSION_PRODUCT=\"$BOARDTYPE"\" >> .config
|
|
|
|
# Enable Package source tree override if selected
|
|
[ $SRCTREEOVERR -eq 1 ] && echo CONFIG_SRC_TREE_OVERRIDE=y >> .config
|
|
|
|
# developer mode selected ?
|
|
echo "CONFIG_DEVEL=y" >>.config
|
|
if [ $DEVELOPER -eq 1 ]; then
|
|
# rewrite url to clone with ssh instead of http
|
|
echo "CONFIG_GITMIRROR_REWRITE=y" >>.config
|
|
else
|
|
echo "# CONFIG_GITMIRROR_REWRITE is not set" >>.config
|
|
fi
|
|
|
|
if [ -n "$BRCM_MAX_JOBS" ]
|
|
then
|
|
echo "CONFIG_BRCM_MAX_JOBS=\"1\"" >>.config
|
|
fi
|
|
|
|
# Force regeneration of kernel Makefile
|
|
# Needed to disable kmods for iopsys-brcm targets
|
|
touch package/kernel/linux/Makefile
|
|
|
|
# we need to signal to bradcom SDK that we have changed the board id
|
|
# currently boardparms.c and boardparms_voice.c is the only place that is depending on boardid name
|
|
# so just touch that file.
|
|
[ -d ./build_dir ] && find build_dir/ -name "boardparms*c" -print0 2>/dev/null | xargs -0 touch 2>/dev/null
|
|
|
|
# Store generated config
|
|
cp .config .genconfig.config
|
|
|
|
# Set default values based on selected parameters
|
|
v "$(make defconfig 2>&1)"
|
|
|
|
echo Set version to $(grep -w CONFIG_TARGET_VERSION .config | cut -d'=' -f2 | tr -d '"')
|
|
|
|
# Clean base-file package to force rebuild when changing profile
|
|
v "$(make package/base-files/clean 2>&1)"
|
|
|
|
verify_config
|
|
}
|
|
|
|
####### main #####
|
|
if [ ! -e tmp/.iop_bootstrap ]; then
|
|
echo "You have not installed feeds. Running genconfig in this state would create a non functional configuration."
|
|
echo "Run: iop feeds_update"
|
|
exit 0
|
|
fi
|
|
|
|
if [ $# -eq 0 ]; then
|
|
echo Current profile:
|
|
cat $CURRENT_CONFIG_FILE
|
|
echo "Try ./iop genconfig -h' to get instructions if you want to change current config"
|
|
exit 0
|
|
else
|
|
while [ -n "$1" ]; do
|
|
case "$1" in
|
|
|
|
-c|--clean) export CLEAN=1;;
|
|
-n|--no-update) export IMPORT=0;;
|
|
-v|--verbose) export VERBOSE="$(($VERBOSE + 1))";;
|
|
-t|--target) export TARGET="$2"; shift;;
|
|
-p|--profile) export PROFILE="$2"; shift;;
|
|
-r|--repo) export CUSTREPO="$2"; shift;;
|
|
-s|--override) export SRCTREEOVERR=1;;
|
|
-S|--brcmsingel) export BRCM_MAX_JOBS=1;;
|
|
-h|--help) usage;;
|
|
-l|--list) list_customers 0 $2;;
|
|
-a|--list-all)list_customers 1;;
|
|
-b|--boards)set_target LIST;exit 0;;
|
|
-*)
|
|
echo "Invalid option: $1 "
|
|
echo "Try -h or --help for more information."
|
|
exit 1
|
|
;;
|
|
*) break;;
|
|
esac
|
|
shift;
|
|
done
|
|
|
|
CUSTREPO="${CUSTREPO:-git@dev.iopsys.eu:consumer/iopsys.git}"
|
|
|
|
setup_dirs
|
|
create_and_copy_files "$@"
|
|
fi
|
|
}
|
|
|
|
register_command "genconfig" "Generate configuration for board and customer"
|