diff --git a/support/functions/_plugin_update_toolchain b/support/functions/_plugin_update_toolchain index cc4bd5f..2d2aeb3 100644 --- a/support/functions/_plugin_update_toolchain +++ b/support/functions/_plugin_update_toolchain @@ -3,7 +3,7 @@ #simplebuild_plugin tcupdate tcupdate(){ - pversion="0.14.3"; + pversion="0.15.0"; pname="s3.TUP"; pdesc="Plugin $pname v$pversion"; configname="$configdir/plugin_update_toolchain.config"; @@ -18,7 +18,7 @@ tcupdate(){ OPTION2="$3"; [ -z "$4" ] && FLAG="0" || FLAG="$4"; #0 - tcupdate call from s3.TUP itself, 1 - tcupdate call from s3 main menu, 2 - tcupdate call from s3 toolchain menu; tc="$CMDTC"; - + #some migrations to upgrade older s3.TUP versions [[ -z "$4" || "$FLAG" -gt "0" ]] && clear && _migrations; @@ -29,7 +29,7 @@ tcupdate(){ if [ "$CMDTC" == "-r" ] || [ "$CMDTC" == "--reset" ];then if [ -f "$configname" ];then if ! _check_github_api_limits 12;then - echo -e "$y_l""RESET -> Moving existing config file...""$re_"; + echo -e "${y_l}RESET -> Moving existing config file...${re_}"; bcn="$configname".$(date +"%Y%m%d%H%M%S"); mv "$configname" "$bcn" echo -e "config file backup='$bcn'\n"; @@ -42,7 +42,7 @@ tcupdate(){ #create config if [ ! -f "$configname" ];then - echo -e "$g_l""CLEANUP -> Creating new config file. Please wait...""$y_l""$re_"; + echo -e "${g_l}CLEANUP -> Creating new config file. Please wait...${y_l}${re_}"; if ! _create_config;then exit; else @@ -88,7 +88,7 @@ tcupdate(){ fi; elif [ "$CMDTC" == "-d" ] || [ "$CMDTC" == "--duplicate" ];then #duplicate toolchain if _check_toolchain "$OPTION1";then - ! _check_toolchain "$OPTION2" && _toolchain_repair "$(_backup "$OPTION1" "$OPTION2")" || echo -e "\n\n$r_l $txt_error:$y_l $OPTION2$w_l Toolchain already exists!""$rs_" && _nl && exit; + ! _check_toolchain "$OPTION2" && _toolchain_repair "$(_backup "$OPTION1" "$OPTION2")" || echo -e "\n\n${r_l} ${txt_error}:${y_l} ${OPTION2}${w_l} Toolchain already exists!${rs_}" && _nl && exit; bye; else _nl && exit; @@ -96,7 +96,7 @@ tcupdate(){ elif [ "$CMDTC" == "-ctng" ] || [ "$CMDTC" == "--crosstool-ng" ] || [ "$CMDTC" == "-fng" ] || [ "$CMDTC" == "--freetz-ng" ];then #toolchain editor menu _tpl_editor "$(_get_template_type "$cttpldir/$OPTION1")" "$OPTION1"; bye; - elif [ -z "$CMDTC" ];then + elif [ -z "$CMDTC" ];then #show toolchain menu unset menu_close; while [ ! $menu_close ] do @@ -126,7 +126,7 @@ tcupdate(){ case $ret in 0) #Update toolchain - menu_close="1";; + _integrate_libs "$tc" "" "1";; 1) #Start crosstool-NG _create_tc "" "" "1";; 2) #Backup toolchain @@ -136,65 +136,73 @@ tcupdate(){ [ "$FLAG" == "1" ] && return || bye;; esac; done; + elif [ -n "$tc" ];then #update toolchain + _integrate_libs "$tc" "$OPTION1" "$FLAG"; + [ "$FLAG" -gt "0" ] && return || bye; fi; +}; +_integrate_libs(){ + local tc="$1" libkeys="$2" menu_close props i icount; + #toolchain native not supported and exists check - if ! _check_toolchain $tc;then - [ -z "$CMDTC" ] && sleep 2 && tcupdate "$CMDTC" "$OPTION1" "$OPTION2" "$FLAG" || _nl && [ "$FLAG" == "1" ] || [ "$FLAG" == "2" ] && sleep 2 && return || exit; + if ! _check_toolchain "$tc";then + _nl && [ "$FLAG" -gt "0" ] && sleep 2 && return || exit; fi; - #load toolchain config - [ -f "$tccfgdir/$tc" ] && source "$tccfgdir/$tc"; - cd "$tcdir/$tc/bin"; + #get toolchain properties + props=$(_get_toolchain_properties "$tc"); + compilername=$(echo "$props" | awk -F';' '{print $1}' | xargs); + ranlibname=$(echo "$props" | awk -F';' '{print $2}' | xargs); + includedir=$(echo "$props" | awk -F';' '{print $3}' | xargs); + sysrootdir=$(echo "$props" | awk -F';' '{print $4}' | xargs); + prefixdir=$(echo "$props" | awk -F';' '{print $5}' | xargs); + pkgconfigdir=$(echo "$props" | awk -F';' '{print $6}' | xargs); + hostname=$(echo "$props" | awk -F';' '{print $7}' | xargs); - #autodetect toolchain's sysroot, prefix, include - compilername="$_compiler""gcc";compilername=$(realpath -s $compilername); - ranlibname="$_compiler""ranlib";ranlibname=$(realpath -s $ranlibname); - hostname=${_compiler%?}; - incdir=$(realpath -s $(echo | "$compilername" -Wp,-v -xc - -fsyntax-only 2>&1 | grep include$ | tail -n 1 | xargs)) - sr=$("$compilername" -print-sysroot 2>/dev/null); - sr=$(realpath -sm "$sr" 2>/dev/null); - if [ ${#sr} -gt ${#tcdir} ];then - [ -d "$sr/include" ] && cd "$sr" - [ -d "$sr/usr/include" ] && [ ! "$(realpath $(readlink -- "$PWD") 2>/dev/null)" == "$(realpath "$sr/usr")" ] && cd "$sr/usr" #Ignore symlinks to the same directory - else - cd "$tcdir/$tc/$_sysroot" - fi; - prefixdir="$PWD" - - [ "$FLAG" == "1" ] && backxit=1 || backxit=$menu_close; - unset menu_close; while [ ! $menu_close ] do - #autodetect toolchain's pkgconfig folder - pkg=$(find * | grep -m1 "/pkgconfig") && pkgdir="$prefixdir/$pkg" || pkgdir="$prefixdir"; - cd "$prefixdir" + #update current toolchain pkgconfig + pkgconfigdir=$(_get_toolchain_pkgconfig "$prefixdir"); + + #get current toolchain libs + tc_libs=$(_get_toolchain_libs "$pkgconfigdir"); #semicolon separeted "pkgname|version|key|compare|libname" + #LIBRARY UPDATE MENU - unset MENU_OPTIONS;COUNT=0;unset libs; + unset MENU_OPTIONS;COUNT=0;unset libs;unset libversioncurrent;unset libversioncompare; for i in "${LIBS[@]}" do [ "${!i}" == "0" ] && continue; libkey=$i; libbeta="$i"_beta; [ "$LIBS_LIST_BETA" == "0" ] && [ "${!libbeta}" == "1" ] && continue; #skip beta libraries in list - libname="$i"_name;libname=${!libname}; - libversion="$i"_version;libversion=${!libversion}; - libdesc="$i"_desc;libdesc=${!libdesc}; - [ ${#libdesc} -eq 0 ] && libdesc="$libname $libversion"; - libcheck="$i"_check;libcheck=${!libcheck}; + libname="$i"_name;libname="${!libname}"; + libversion="$i"_version;libversion="${!libversion}"; + libdesc="$i"_desc;libdesc="${!libdesc}"; + [ "${#libdesc}" -eq 0 ] && libdesc="$libname $libversion"; + libcheck="$i"_check;libcheck="${!libcheck}"; libversioncheck=$(echo "$libcheck" | awk '{printf $2}') libcheck=$(echo "$libcheck" | awk '{printf $1}') - liburl="$i"_url;liburl=${!liburl}; - libversioncurrent=$(_get_version "$pkgdir/$libcheck" "$libversioncheck"); - libversioncompare=$(_compare_version $libversion $(echo $libversioncurrent | sed -e 's/^$/0.0.0/g')); + liburl="$i"_url;liburl="${!liburl}"; libtasks="$i"_tasks[@];libtasks=("${!libtasks}"); - libexports="$i"_exports[@];libexports=("${!libexports}"); - libconfigure="$i"_configure[@];libconfigure=("${!libconfigure}"); - libmake="$i"_make[@];libmake=("${!libmake}"); + + # check match of existing lib + for l in $(echo "$tc_libs" | tr ";" "\n") #semicolon separeted "pkgname|version|key|compare|libname" + do + key=$(echo "$l" | awk -F'|' '{print $3}' | xargs); + if [ "$key" == "$libkey" ];then + libversioncurrent=$(echo "$l" | awk -F'|' '{print $2}' | xargs); + libversioncompare=$(echo "$l" | awk -F'|' '{print $4}' | xargs); + break; + else + libversioncurrent=""; + libversioncompare=""; + fi; + done; #Preselection and formatting [ "$libversioncompare" == "=" ] && libtxtfmt="\Z2" || libtxtfmt=""; [ "$libversioncompare" == "<" ] && libtxtfmt="\Z1"; - [ "$libversioncompare" == ">" ] && [ ${#libversioncurrent} -gt 0 ] && libselected="on" && libtxtfmt="\Z5" || libselected="off"; + [ "$libversioncompare" == ">" ] && [ "${#libversioncurrent}" -gt 0 ] && libselected="on" && libtxtfmt="\Z5" || libselected="off"; MENU_OPTIONS+=("$i" "$libdesc""$(printf '%*s' $((24-${#libdesc})))""$libtxtfmt$([ $libversioncurrent ] && echo $libversioncompare) $(echo $libversioncurrent | sed -e 's/^$/ ---/g')\Zn" "$(echo $libselected)" "$([ $libname ] && echo "$libdesc: $liburl")");counter; @@ -204,31 +212,35 @@ tcupdate(){ done; [ $COUNT -eq 0 ] && MENU_OPTIONS+=("" "no libraries found" "no libraries found") && counter; - if [ ${#OPTION1} -gt 0 ];then #Force build library call - opts=$(echo "$OPTION1" | tr ',' '\n'); + if [ "${#libkeys}" -gt 0 ];then #Force integrate libs call + opts=$(echo "$libkeys" | tr ',' '\n'); ret="0"; else clear;clear; - opts=$("$gui" "--item-help" "--help-tags" "$st_" "$bt_" "$title_ - \Z0$pdesc\Zn" "--colors" "--default-item" "$lkey" "--ok-label" "Start" "--help-button" "--help-label" "Info" "--cancel-label" "$([ "$backxit" == "1" ] && echo "Back" || echo "Exit")" "--title" "-[ Library Update Menu - \Z2$tc\Zn ]-" "$cl_"\ + opts=$("$gui" "--item-help" "--help-tags" "$st_" "$bt_" "$title_ - \Z0$pdesc\Zn" "--colors" "--default-item" "$lkey" "--ok-label" "Start" "--help-button" "--help-label" "Info" "--cancel-label" "$([ ! "$3" -gt "0" ] && echo "Exit" || echo "Back")" "--title" "-[ Library Update Menu - \Z2$tc\Zn ]-" "$cl_"\ "\nSelect all libraries to update in toolchain's SYSROOT folder:\n$prefixdir\n\n library version NEW CURRENT" \ "${COUNT+12}" 70 0 "${MENU_OPTIONS[@]}"); ret="$?" fi; + #sort opts descending to ensure LIB_USB is build before LIB_PCSC + opts=$(echo "$opts" | tr ' ' '\n' | sort -hr); + #SSL select check - [ $(echo $opts | tr ' ' '\n' | grep -c "SSL_") -gt 1 ] && echo -e $r_l"\n\nPlease select only one SSL version!"$re_ && sleep 3 && [ ${#OPTION1} -gt 0 ] && menu_close=1 && continue; + [ $(echo $opts | tr ' ' '\n' | grep -c "SSL_") -gt 1 ] && echo -e "${r_l}\n\nPlease select only one SSL version!${re_}" && sleep 3 && [ "${#OPTION1}" -gt 0 ] && menu_close=1 && continue; case $ret in 0) #Start - Build library ts=$(date +%F.%H%M%S); tmpdir="/tmp/lib_source/$ts"; icount=$(echo $opts | wc -w);i=0; + for o in $opts;do unset buildtasks; for l in "${libs[@]}";do declare -a lib="${l[*]}"; #populate libs array element [ ! "$o" == "${lib[0]}" ] && continue || ((i++)); - logfile="$ldir/"$ts"_tup_"$_toolchainname"_"${lib[1]}"_"${lib[2]}".log" + logfile="$ldir/${ts}_tup_${tc}_${lib[1]}_${lib[2]}.log" #generate build command list declare -a libtasks="${lib[7]}"; #populate tasks array element @@ -236,13 +248,15 @@ tcupdate(){ task=$(_replace_tokens "$task"); #replace tokens buildtasks+=("$task"); done; - _build "($i/$icount) $tc: library ${lib[1]} ${lib[2]}" $(_extract $(_dl "${lib[6]}" "${lib[1]} ${lib[2]}") "$tmpdir" 2>/dev/null) "$logfile" "${buildtasks[@]}"; + _build_library "($i/$icount) $tc: library ${lib[1]} ${lib[2]}" $(_extract $(_dl "${lib[6]}" "${lib[1]} ${lib[2]}") "$tmpdir" 2>/dev/null) "$logfile" "${buildtasks[@]}"; done; - [ "${#buildtasks[@]}" == "0" ] && echo -e "$r_l $txt_error:$y_l $o$w_l Library not found in config file""$rs_"; + [ "${#buildtasks[@]}" == "0" ] && echo -e "${r_l} ${txt_error}:${y_l} ${o}${w_l} Library not found in config file${rs_}"; done; + [ -d "$tmpdir" ] && rm -r "$tmpdir";; 1) #Exit/Back - menu_close="1";; + menu_close="1"; + return;; 2) #Info first=$(echo "$opts" | awk '{printf $1}'); lkey=$(echo "$opts" | awk '{printf $2}'); @@ -251,7 +265,7 @@ tcupdate(){ sp=$(printf '%*s' 90 | tr ' ' '='); txt=$(cat "$configname" | grep ""$lkey"=\|"$lkey"_"); bcd=$(cat "$configname" | grep ""$lkey"_tasks"); - txt=$(echo -e "Toolchain: $tcdir/$tc\nCompiler: $compilername\nSysroot: $sr\nPrefix: $prefixdir\nInclude: $incdir\n$sp\n\nLibrary configuration:\n$txt\n\nBuild command:\n$(_replace_tokens "$(_tidy_tasks "$bcd" "$lkey")")"); + txt=$(echo -e "Toolchain: $tcdir/$tc\nCompiler: $compilername\nSysroot: $sysrootdir\nPrefix: $prefixdir\nInclude: $includedir\n$sp\n\nLibrary configuration:\n$txt\n\nBuild command:\n$(_replace_tokens "$(_tidy_tasks "$bcd" "$lkey")")"); tempfile=$(mktemp) && echo -e "$txt" > "$tempfile"; "$gui" "$st_" "$nc_" "$bt_" "$title_ - \Z0$pdesc\Zn" "--colors" "--ok-label" "Back" "--textbox" "$tempfile" 30 80; rm "$tempfile" 2>/dev/null; @@ -259,27 +273,18 @@ tcupdate(){ esac; #Exit loop if build library is forced - [ ${#OPTION1} -gt 0 ] && menu_close=1; + [ "${#libkeys}" -gt 0 ] && menu_close=1; done; - - #Reopen previous menu - [ ${#OPTION1} -gt 0 ] && exit; - [ "$FLAG" == "2" ] && return; - if [ ${#opts} -gt 0 ];then - tcupdate "$tc" "$OPTION1" "$OPTION2" "$backxit"; - else - [ "$backxit" == "1" ] && tcupdate "" "$OPTION1" "$OPTION2" "$FLAG" || bye; - fi; }; _create_tc(){ _sz; # Prepare DIALOG settings unset TPL_LIST; - local menu_close; + local menu_close libkeys; while [ ! $menu_close ] do - if [ ${#2} -gt 0 ];then #Force setup call + if [ "${#2}" -gt 0 ];then #Force setup call ret="1"; - elif [ ${#1} -gt 0 ];then #Force build toolchain call + elif [ "${#1}" -gt 0 ];then #Force build toolchain call opts="$1"; ret="0"; else #Show Template Menu @@ -331,12 +336,30 @@ _create_tc(){ for tpl in $opts;do if [ -f "$cttpldir/$tpl" ];then + #get existing toolchain properties to detect current toolchain libs + unset libkeys; + if [ -d "$tcdir/$tpl" ];then + props=$(_get_toolchain_properties "$tpl"); + prefixdir=$(echo "$props" | awk -F';' '{print $5}' | xargs); + pkgconfigdir=$(echo "$props" | awk -F';' '{print $6}' | xargs); + + #get current toolchain libs + tc_libs=$(_get_toolchain_libs "$pkgconfigdir"); #semicolon separeted "pkgname|version|key|compare|libname" + for l in $(echo "$tc_libs" | tr ";" "\n") + do + key=$(echo "$l" | awk -F'|' '{print $3}' | xargs); + [ -n "$key" ] && libkeys+="${key},"; + done; + + libkeys="$(echo "${libkeys%?}" | xargs)"; + fi; + logfile="$ldir/$(date +%F.%H%M%S)_tup_crosstoolchain_"$tpl".log"; ((i++)); clear; sp=$(printf '%*s' 80 | tr ' ' '=') echo -e "$pdesc - creating cross toolchain log - $(date +"%F %T")" | tee -a "$logfile"; - echo -e "$y_l$sp\nbuild ($i/$icount): command list for cross toolchain $tpl:\n$sp" | tee -a "$logfile"; + echo -e "${y_l}$sp\nbuild ($i/$icount): command list for cross toolchain $tpl:\n$sp" | tee -a "$logfile"; #copy template [ $(_get_template_type "$cttpldir/$tpl") == "CTNG" ] && tpltargetdir="$ctngsrcdir"; @@ -367,14 +390,18 @@ _create_tc(){ #run build [ $(_get_template_type "$cttpldir/$tpl") == "CTNG" ] && bcl=$(printf '%s\n' "${CTNG_BUILD_tasks[@]}"); [ $(_get_template_type "$cttpldir/$tpl") == "FNG" ] && bcl=$(printf '%s\n' "${FNG_BUILD_tasks[@]}"); - echo -e "cd \"$tpltargetdir\";\n$(_replace_tokens "$bcl")\n$sp""$re_" | tee -a "$logfile"; + echo -e "cd \"${tpltargetdir}\";\n$(_replace_tokens "$bcl")\n$sp${re_}" | tee -a "$logfile"; sleep 2; if [ $CTNG_START_BUILD -eq 1 ];then cd "$tpltargetdir"; + + #print out detected libs in current toolchain + [ "${#libkeys}" -gt 0 -a "$LIBS_AUTO_INTEGRATE" -eq 1 ] && echo -e "${y_l}\nThe following libraries were detected in the existing toolchain:\n${b_l}$(echo "$libkeys" | tr ',' '\n' | sort -hr)${re_}" | tee -a "$logfile"; + #print out crosstool version - [ $(_get_template_type "$cttpldir/$tpl") == "CTNG" ] && echo -e "$g_l\n$(./ct-ng | grep 'crosstool-NG version' &2>/dev/null | tail -1)\n""$re_" | tee -a "$logfile"; - [ $(_get_template_type "$cttpldir/$tpl") == "FNG" ] && echo -e "$g_l\n$(tools/freetz-revision 2>&1 | tail -1)\n""$re_" | tee -a "$logfile"; + [ $(_get_template_type "$cttpldir/$tpl") == "CTNG" ] && echo -e "${g_l}\n$(./ct-ng | grep 'crosstool-NG version' &2>/dev/null | tail -1)\n${re_}" | tee -a "$logfile"; + [ $(_get_template_type "$cttpldir/$tpl") == "FNG" ] && echo -e "${g_l}\n$(tools/freetz-revision 2>&1 | tail -1)\n${re_}" | tee -a "$logfile"; #generate build command list unset buildtasks; @@ -423,6 +450,12 @@ _create_tc(){ #save config in target toolchain folder [ -f "$tpltargetdir/.config" ] && cp -f "$tpltargetdir/.config" "$tcdir/$tpl/"; + #auto integrate libs + if [ "${#libkeys}" -gt 0 -a "$LIBS_AUTO_INTEGRATE" -eq 1 ];then + echo -e "${y_l}\nThe following libraries will now be integrated into the toolchain:\n${b_l}$(echo "$libkeys" | tr ',' '\n' | sort -hr)${re_}" | tee -a "$logfile"; + _integrate_libs "$tpl" "$libkeys" "$FLAG"; + fi; + #compress toolchain _compress "$dldir/Toolchain-$tpl.tar.xz" "$tcdir/$tpl" | "$gui" "$st_" "$bt_" "$title_ - \Z0$pdesc\Zn" "--colors" "--title" " -[ Compress cross toolchain $tpl to Toolchain-$tpl.tar.xz ]- " "$pb_" "$_lines" "$_cols"; @@ -434,11 +467,11 @@ _create_tc(){ _paktc_timer 10; fi; else - echo -e "$r_l""$CTNG_ROOT_BUILD_ERROR""$y_l""$CTNG_ROOT_BUILD_CMD""$re_" | tee -a "$logfile"; + echo -e "${r_l}${CTNG_ROOT_BUILD_ERROR}${y_l}${CTNG_ROOT_BUILD_CMD}${re_}" | tee -a "$logfile"; _paktc_timer 10; fi; else - echo -e "$r_l $txt_error:$y_l $tpl$w_l Template $txt_n_installed""$rs_"; + echo -e "${r_l} ${txt_error}:${y_l} ${tpl}${w_l} Template ${txt_n_installed}${rs_}"; sleep 2; fi; done;; @@ -452,14 +485,13 @@ _create_tc(){ menu_close="1"; return;; esac; - + #Exit loop if setup or build toolchain are forced - [ ${#2} -gt 0 ] || [ ${#1} -gt 0 ] && menu_close=1; + [ "${#2}" -gt 0 ] || [ "${#1}" -gt 0 ] && menu_close=1; done; }; _migrations(){ - #rename folder for compatibility with pre 0.13.x releases [ -d "$ctdir/source" ] && mv -f "$ctdir/source" "$ctngsrcdir"; @@ -491,7 +523,6 @@ _migrations(){ fi; }; _backup(){ - _sz; # Prepare DIALOG settings src=$1; dest=$2; @@ -508,14 +539,12 @@ _backup(){ ) | "$gui" "$st_" "$bt_" "$title_ - \Z0$pdesc\Zn" "--colors" "--title" " -[ Backup $src to $(basename "$xzfile") ]- " "$pb_" "$_lines" "$_cols"; [ -f "$newtccfgfile" ] && echo "$dest"; }; -_build(){ +_build_library(){ _sz; # Prepare DIALOG settings - local desc="$1"; # Save 1. argument in a variable - local libsrcdir="$2"; # Save 2. argument in a variable - local lf="$3"; # Save 3. argument in a variable - shift && shift && shift;# Shift all 3. arguments to the left (original $1,$2,$3 gets lost) + local desc="$1" libsrcdir="$2" lf="$3"; # Save the first 3 arguments in variables + shift 3; # Shift all 3 arguments to the left (original $1,$2,$3 gets lost) local tasks=("$@"); # Rebuild the array with rest of arguments - + ( bcl=$(printf '%s\n' "${tasks[@]}"); @@ -530,9 +559,9 @@ _build(){ #build error message error_on_build=$(grep -cw1 Error "$lf"); if [ "$error_on_build" -gt "0" ];then - echo -e ""$r_l"ERRORS on build found, details:\n$b_l $lf\n$y_l" >$(tty); + echo -e "${r_l}ERRORS on build found, details:\n${b_l} ${lf}\n${y_l}" >$(tty); _paktc_timer 10; - echo -e "$re_$w_l"; + echo -e "${re_}${w_l}"; fi; }; @@ -556,7 +585,7 @@ _tpl_editor(){ fi; cd "$editordir"; - TASKS=${1}_CONFIG_tasks[@];TASKS=("${!TASKS}"); + TASKS="${1}"_CONFIG_tasks[@];TASKS=("${!TASKS}"); for task in "${TASKS[@]}";do task=$(_replace_tokens "$task"); #replace tokens @@ -720,6 +749,77 @@ _tidy_tasks(){ s#"\"\)\;"##g; \ s#"\'\)\;"##g;"; }; +_get_toolchain_properties(){ + local tc="$1" props; + + #load toolchain config + [ -f "$tccfgdir/$tc" ] && source "$tccfgdir/$tc"; + + #jump into toolchains bin folder + cd "$tcdir/$tc/bin" + + #autodetect toolchain's properties + compilername="$_compiler""gcc";compilername=$(realpath -s $compilername); + ranlibname="$_compiler""ranlib";ranlibname=$(realpath -s $ranlibname); + hostname="${_compiler%?}"; + includedir=$(realpath -s $(echo | "$compilername" -Wp,-v -xc - -fsyntax-only 2>&1 | grep include$ | tail -n 1 | xargs)) + sysrootdir="$(realpath -sm "$("$compilername" -print-sysroot 2>/dev/null)" 2>/dev/null)"; + + if [ "${#sysrootdir}" -gt "${#tcdir}" ];then + [ -d "$sysrootdir/include" ] && cd "$sysrootdir" + [ -d "$sysrootdir/usr/include" ] && [ ! "$(realpath $(readlink -- "$PWD") 2>/dev/null)" == "$(realpath "$sysrootdir/usr")" ] && cd "$sysrootdir/usr" #Ignore symlinks to the same directory + else + cd "$tcdir/$tc/$_sysroot" + fi; + prefixdir="$PWD" + + pkgconfigdir="$(_get_toolchain_pkgconfig "$prefixdir")"; + + props="$compilername;$ranlibname;$includedir;$sysrootdir;$prefixdir;$pkgconfigdir;$hostname" + echo "$props" | xargs; + [ -n "$props" ] && exit 0 || exit 1; +}; +_get_toolchain_pkgconfig(){ + local prefixdir="$1"; + cd "$prefixdir" + pkg=$(find * | grep -m1 "/pkgconfig") && pkgconfigdir="$prefixdir/$pkg" || pkgconfigdir="$prefixdir"; + echo "$pkgconfigdir" | xargs; + [ -n "$pkgconfigdir" ] && exit 0 || exit 1; +}; +_get_toolchain_libs(){ + local pkgconfigdir="$1" key libs; + cd "$pkgconfigdir" + + #looking for existing libraries + for pkg in *.pc + do + [ -f "$pkg" ] && content=$(cat "$pkg") && name=$(echo "$content" | grep 'Name:' | sed -e "s/Name: //g") && version=$(echo "$content" | grep 'Version:' | sed -e "s/Version: //g") + + if [ ! -z "$pkg" -a ! -z "$name" -a ! -z "$version" ];then + #try match with library from config + for l in "${LIBS[@]}" + do + [ "${!l}" == "0" ] && continue; + libcheck="$l"_check;libcheck="${!libcheck}"; + libversion="$l"_version;libversion="${!libversion}"; + libversioncompare=$(_compare_version $libversion $version); + if [[ "$pkg $version" =~ ^${libcheck}.* ]];then #regex match, don't quote the right side + key="$l"; + compare="$libversioncompare"; + break; + else + unset key && unset compare; + fi; + done; + + [ -n "$key" ] && libs+="$pkg\|$version\|$key\|$compare\|$name;"; + fi; + + done; + + echo "${libs%?}" | xargs; + [ -n "$libs" ] && exit 0 || exit 1; +}; _get_template_properties(){ desc=""; if [ -f "$1" ];then @@ -799,20 +899,6 @@ _get_template_type(){ echo "CTNG"; fi; }; -_get_version(){ - r=""; - if [ -f "$1" ];then - content=$(cat "$1"); - ver=$(echo "$content" | grep 'Version:' | sed -e "s/Version: //g"); - if [ -z "$2" ];then - r="$ver"; - else - (echo "$ver" | grep -qc "$2") && r="$ver"; - fi; - fi; - echo $r; - [ ${#r} -gt 0 ] && exit 0 || exit 1; -}; _compare_version(){ min=$(printf "$1\n$2\n" | sort -V | head -n1); @@ -841,31 +927,31 @@ echo -e "\033[2K\r"; #remove characters from console _check_toolchain(){ if [ -z "$1" ];then #toolchain parameter empty - echo -e "\n\n$r_l $txt_error:$y_l Parameter$w_l Toolchain not set!""$rs_"; + echo -e "\n\n${r_l} ${txt_error}:${y_l} Parameter${w_l} Toolchain not set!${rs_}"; return 1; elif [ "$1" == "native" ];then #toolchain native not supported - echo -e "\n\n$r_l $txt_error:$y_l $1$w_l Toolchain library update not supported!""$rs_"; + echo -e "\n\n${r_l} ${txt_error}:${y_l} ${1}${w_l} Toolchain library update not supported!${rs_}"; return 1; elif [ ! -d "$tcdir/$1/bin" ];then #toolchain not installed - echo -e "\n\n$r_l $txt_error:$y_l $1$w_l Toolchain $txt_n_installed""$rs_"; + echo -e "\n\n${r_l} ${txt_error}:${y_l} ${1}${w_l} Toolchain ${txt_n_installed}${rs_}"; return 1; else return 0; fi; }; _check_root(){ - ! ((${EUID:-0} || "$(id -u)")); + ! (("${EUID:-0}" || "$(id -u)")); }; _check_lib(){ case "$1" in "PCSC") #Create symlink to the PCSC header files, if the last include path of the compiler don't point to it echo -e "\nCheck for PCSC header files and try to symlink to the correct PCSC header files if the last compiler include path points to the wrong location..."; - if [ ${#incdir} -gt 0 ] && [ ! -d "$incdir/PCSC" ];then + if [ "${#includedir}" -gt 0 ] && [ ! -d "$includedir/PCSC" ];then headerdir="$(dirname $(find "$prefixdir" -type f -name "pcsclite.h" | head -n 1))"; - [ ${#headerdir} -gt 0 ] && ln -s "$(realpath --relative-to="$incdir" "$headerdir")" "$incdir/PCSC"; - [ ${#headerdir} -gt 0 ] && echo "Symlink $incdir/PCSC -> $headerdir created, to point to the PCSC header files." || "No PCSC header files found in $prefixdir and it's sub directories!"; + [ "${#headerdir}" -gt 0 ] && ln -s "$(realpath --relative-to="$includedir" "$headerdir")" "$includedir/PCSC"; + [ "${#headerdir}" -gt 0 ] && echo "Symlink $includedir/PCSC -> $headerdir created, to point to the PCSC header files." || "No PCSC header files found in $prefixdir and it's sub directories!"; else - [ ${#incdir} -gt 0 ] && echo "PCSC header files are in the correct location: $incdir/PCSC" || echo "Compiler returns no include directories!"; + [ "${#includedir}" -gt 0 ] && echo "PCSC header files are in the correct location: $includedir/PCSC" || echo "Compiler returns no include directories!"; fi;; *) echo "not implemented yet!"; esac; @@ -876,9 +962,9 @@ _check_pkg(){ composite inkscape pkg-config python gettext ruby ); headers=( ncurses libacl.h sys/capability.h readline.h glib-2.0/glib.h ); libs=( libstdc++.so.6 libstdc++.a libc\\.a ); - echo -e "$y_l""SYSCHECK -> Please wait while performing checks of required tools and dependencies...""$re_"; + echo -e "${y_l}SYSCHECK -> Please wait while performing checks of required tools and dependencies...${re_}"; if syscheck "" "" "${pkgs[*]}" "${headers[*]}" "${libs[*]}";then - echo -e "$r_l""\nSYSCHECK -> You need to manually install the following packages to use this plugin properly:\n"$y_l"$prefix install$packages\n""$re_" && _paktc_timer 10; + echo -e "${r_l}\nSYSCHECK -> You need to manually install the following packages to use this plugin properly:\n${y_l}${prefix} install${packages}\n${re_}" && _paktc_timer 10; fi; }; _check_github_api_limits(){ @@ -889,12 +975,12 @@ _check_github_api_limits(){ reset_time=$(date -d @$reset); if [ "$remaining" -lt "$1" ];then - echo -e "$y_l""NOTE -> Please wait until "$g_l"$reset_time"$y_l" to reset your configuration file."\ + echo -e "${y_l}NOTE -> Please wait until ${g_l}${reset_time}${y_l} to reset your configuration file."\ "The most recent versions and download links for the libraries are determined dynamically via the Github API."\ "Exceeding the rate limit on Github API will result in failures on generationg the configuration file."\ "Your Github API rate limit will be reset soon on $reset_time."\ - "\nFor "$b_l"unauthenticated requests"$y_l", the rate limit allows for "$b_l"up to $limit requests per hour"$y_l". Unauthenticated requests are associated with the originating IP address, and not the user making requests."\ - "\n$re_"; + "\nFor ${b_l}unauthenticated requests${y_l}, the rate limit allows for ${b_l}up to ${limit} requests per hour${y_l}. Unauthenticated requests are associated with the originating IP address, and not the user making requests."\ + "\n${re_}"; return 0; else return 1; @@ -905,7 +991,7 @@ _check_crosstool_setup(){ if [ "$1" == "CTNG" ] || [ -z "$1" ];then if [ ! -f "$ctngsrcdir/ct-ng" ];then clear; - echo -e "$r_l""\nCHECK -> crosstool-NG is not setup correctly. Try to fix it automatically...\n""$re_"; + echo -e "${r_l}\nCHECK -> crosstool-NG is not setup correctly. Try to fix it automatically...\n${re_}"; [ -z "$1" ] && _paktc_timer 5; _ctng_setup "$CTNG_START_BUILD"; fi; @@ -915,7 +1001,7 @@ _check_crosstool_setup(){ if [ "$1" == "FNG" ] || [ -z "$1" ];then if [ ! -d "$fngsrcdir/dl" ];then clear; - echo -e "$r_l""\nCHECK -> Freetz-NG is not setup correctly. Try to fix it automatically...\n""$re_"; + echo -e "${r_l}\nCHECK -> Freetz-NG is not setup correctly. Try to fix it automatically...\n${re_}"; [ -z "$1" ] && _paktc_timer 5; _fng_setup "$CTNG_START_BUILD"; fi; @@ -923,16 +1009,17 @@ _check_crosstool_setup(){ }; _check_config(){ nok=0; - [ -z ${LIBS_LIST_BETA+x} ] && nok=1; - [ -z ${FNG_REPO_URL+x} ] && nok=1; - [ -z ${CTNG_CONFIG_tasks+x} ] && nok=1; - [ -z ${CTNG_BUILD_AS_ROOT+x} ] && nok=1; - [ -z ${LIBS+x} ] && nok=1; + [ -z "${LIBS_AUTO_INTEGRATE+x}" ] && conf+="LIBS_AUTO_INTEGRATE\n" && nok=1; + [ -z "${LIBS_LIST_BETA+x}" ] && conf+="LIBS_LIST_BETA\n" && nok=1; + [ -z "${FNG_REPO_URL+x}" ] && conf+="FNG_REPO_URL\n" && nok=1; + [ -z "${CTNG_CONFIG_tasks+x}" ] && conf+="CTNG_CONFIG_tasks\n" && nok=1; + [ -z "${CTNG_BUILD_AS_ROOT+x}" ] && conf+="CTNG_BUILD_AS_ROOT\n" && nok=1; + [ -z "${LIBS+x}" ] && conf+="LIBS\n" && nok=1; if [ $nok -eq 1 ];then clear; - echo -e "$r_l""\nCHECK -> Your config file seems to be outdated. Please restart s3 as follows to recreate an updated config file:\n"$y_l"./s3 tcupdate -r\n""$re_"; - _paktc_timer 10; + echo -e "${r_l}\nCHECK -> Your config file seems to be outdated. The following settings are missing:\n${y_l}${conf}\n${r_l}Please restart s3 as follows to recreate an updated config file:\n${y_l}./s3 tcupdate -r\n${re_}"; + _paktc_timer 20; return $nok; fi; }; @@ -942,16 +1029,16 @@ _change_config(){ [[ ! $2 =~ "(" ]] && [[ ! $string =~ ")" ]] && qte="\"" || qte=""; #no quotes if value contains parentheses if ! grep -Eq "^$1=.*" "$configname";then - echo -e "$r_l""\nCHECK -> Variable "$y_l"$1"$r_l" does not exist in the configuration file!\n""$re_"; + echo -e "${r_l}\nCHECK -> Variable ${y_l}${1}${r_l} does not exist in the configuration file!\n${re_}"; _paktc_timer 10; elif [ "${1:(-6)}" == "_tasks" ];then - echo -e "$r_l""\nCHECK -> Modifying "$y_l"tasks-variables"$r_l" not implemented yet!\n""$re_"; + echo -e "${r_l}\nCHECK -> Modifying ${y_l}tasks-variables${r_l} not implemented yet!\n${re_}"; _paktc_timer 10; else cp -f "$configname" "$configname.$(date +"%Y%m%d%H%M%S")" sed -i "s#^$1=.*#$1=$qte$2$qte; \#changed on $ts via tcupdate commandline#g" "$configname"; result=$(grep -E "^$1=.*" "$configname" | awk '{printf $1}'); - echo -e "$g_l""\nDONE -> Variable changed to: "$y_l"$result\n""$re_"; + echo -e "${g_l}\nDONE -> Variable changed to: ${y_l}${result}\n${re_}"; _paktc_timer 5; nok=0; fi; @@ -960,8 +1047,8 @@ _change_config(){ }; _create_config(){ #check existing jq - if [ ! $(which jq) ];then - echo -e "$r_l""\nCHECK -> Without the tool 'jq' automatic config file generation is not possible. Please install it first:\n"$y_l"apt install jq\n""$re_" && _paktc_timer 10; + if [ ! "$(which jq)" ];then + echo -e "${r_l}\nCHECK -> Without the tool 'jq' automatic config file generation is not possible. Please install it first:\n${y_l}apt install jq\n${re_}" && _paktc_timer 10; return 1; fi; @@ -999,8 +1086,8 @@ _create_config(){ "#Filename and optional version number to check in pkgconfig folder for an existing library to get version information" "#Valid URL for downloading sources of library\n#List of build commands below. Pay attention to the SEMICOLON at the end of EACH\n#command and the correct quoting (' or \") for or to avoid expansion of variables.\n#Tokens @TOOLCHAIN@, @CC@, @RANLIB@, @PREFIX@, @HOST@, @VALIDATE@, @LOGFILE@ are replaced automatically." "#build command" ); - lib_settings=( "" beta name version check url tasks ); - lib_keys=( SAMPLE_LIB SSL_300 SSL_111 SSL_110 SSL_102 SSL_100 SSL_098 LIB_USB LIB_PCSC LIB_ZLIB ); + lib_settings=( "" "beta" "name" "version" "check" "url" "tasks" ); + lib_keys=( "SAMPLE_LIB" "SSL_300" "SSL_111" "SSL_110" "SSL_102" "SSL_100" "SSL_098" "LIB_USB" "LIB_PCSC" "LIB_ZLIB" ); lib_betas=( "0" "1" "0" "0" "0" "0" "0" "0" "0" "0" ); lib_names=( "SampleLib" "OpenSSL" "OpenSSL" "OpenSSL" "OpenSSL" "OpenSSL" "OpenSSL" "libusb" "PCSC-Lite" "zlib" ); lib_versions=( "0.2.9sl" @@ -1044,7 +1131,7 @@ _create_config(){ i=0; for ct in "${ctng_config_tasks[@]}"; do - echo -e "CTNG_CONFIG_tasks"$([ "$i" -gt "0" ] && echo "+")"=$ct; $ctng_config_tasks_comment$(($i+1))" >>"$configname"; + echo -e "CTNG_CONFIG_tasks"$([ "$i" -gt "0" ] && echo "+")"=$ct; $ctng_config_tasks_comment$(($i+1))" >>"$configname"; ((i++)); done; i=0; @@ -1060,7 +1147,7 @@ _create_config(){ ((i++)); done; - echo -e '\nFNG_REPO_URL="https://github.com/Freetz-NG/freetz-ng.git"; #Repository to load freetz-ng from' >>"$configname"; + echo -e '\nFNG_REPO_URL="https://github.com/Freetz-NG/freetz-ng.git"; #Repository to load freetz-ng from' >>"$configname"; i=0; for ct in "${fng_config_tasks[@]}"; do @@ -1083,6 +1170,7 @@ _create_config(){ echo -e '\n#LIBRARY update build settings\n#List of ordered libraries. Only libraries in this list are available' >>"$configname"; echo "LIBS=(${lib_keys[@]});" >>"$configname"; echo 'LIBS_LIST_BETA="0"; #In(Ex)clude libraries defined as beta' >>"$configname"; + echo 'LIBS_AUTO_INTEGRATE="1"; #Automatically integrate libraries into toolchains' >>"$configname"; i=0; for key in "${lib_keys[@]}"; @@ -1091,20 +1179,20 @@ _create_config(){ do case "$setting" in "") if [ -z $setting ];then - echo -e "\n#"${lib_names[$i]}" "${lib_versions[$i]}"" >>"$configname"; + echo -e "\n#${lib_names[$i]} ${lib_versions[$i]}" >>"$configname"; fi; - echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"$([ "$key" == "SAMPLE_LIB" ] && echo '0' || echo '1')\";$([ "$i" -eq "0" ] && echo " ${lib_comments[0]}")" >>"$configname";; - "beta") echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"${lib_betas[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[1]}")" >>"$configname";; - "name") echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"${lib_names[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[2]}")" >>"$configname";; - "version") echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"${lib_versions[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[3]}")" >>"$configname";; + echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"$([ "$key" == "SAMPLE_LIB" ] && echo '0' || echo '1')\";$([ "$i" -eq "0" ] && echo " ${lib_comments[0]}")" >>"$configname";; + "beta") echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"${lib_betas[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[1]}")" >>"$configname";; + "name") echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"${lib_names[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[2]}")" >>"$configname";; + "version") echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"${lib_versions[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[3]}")" >>"$configname";; "check") [ $(echo -e "$key" | grep -c "SSL_\|SAMPLE_") -gt 0 ] && chk="$(echo -e "${lib_checks[$i]} $(echo ${lib_versions[$i]} | sed 's/\([0-9.]*\).*/\1/g')")" || chk="${lib_checks[$i]}"; - echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"$chk\";$([ "$i" -eq "0" ] && echo " ${lib_comments[4]}")" >>"$configname";; - "url") echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting""=\"${lib_urls[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[5]}")" >>"$configname";; + echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"$chk\";$([ "$i" -eq "0" ] && echo " ${lib_comments[4]}")" >>"$configname";; + "url") echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting""=\"${lib_urls[$i]}\";$([ "$i" -eq "0" ] && echo " ${lib_comments[5]}")" >>"$configname";; "tasks") unset tasks;j=0; declare -a tasks="${lib_tasks[$i]}" for t in "${tasks[@]}"; do - echo -e "$key"$([ ! -z $setting ] && echo "_")"$setting"$([ "$j" -gt "0" ] && echo "+")"=$t;$([ "$i" -eq "0" ] && echo " ${lib_comments[6]}$(($j+1))")" >>"$configname"; + echo -e "$key"$([ ! -z "$setting" ] && echo "_")"$setting"$([ "$j" -gt "0" ] && echo "+")"=$t;$([ "$i" -eq "0" ] && echo " ${lib_comments[6]}$(($j+1))")" >>"$configname"; ((j++)); done;; esac; @@ -1119,13 +1207,13 @@ _create_toolchaincfg(){ compilername="$3""-gcc";compilername=$(realpath -s $compilername); sr=$("$compilername" -print-sysroot 2>/dev/null); sr=$(realpath -sm "$sr" 2>/dev/null); - if [ ${#sr} -eq 0 ];then + if [ "${#sr}" -eq 0 ];then sysroot="$4"; else sysroot="${sr#"$1/"}"; fi; - [ ${#5} -gt 0 ] && lsd="$5" || lsd="/usr/lib"; - [ ${#7} -gt 0 ] && info="$7" || info="$(echo -e "\\\n + [ "${#5}" -gt 0 ] && lsd="$5" || lsd="/usr/lib"; + [ "${#7}" -gt 0 ] && info="$7" || info="$(echo -e "\\\n !!! crosstool-NG Toolchain !!!\\\n \\\n $(echo "$6" | awk -F'[()]' '{print $1}' | xargs)\\\n @@ -1147,5 +1235,4 @@ _md5sum="$(cd "$dldir" && md5sum $(basename "${8%..*}"))"; _tc_info="$info"; _tc_infolines="5"; EOF - };