setup_toolchain() { if [ "$LTO_SUPPORT" = "yes" ]; then if flag_enabled "lto-parallel" "no"; then TARGET_CFLAGS+=" $FLAGS_OPTIM_LTO_PARALLEL $FLAGS_OPTIM_LTO_NO_FAT" TARGET_CXXFLAGS+=" $FLAGS_OPTIM_LTO_PARALLEL $FLAGS_OPTIM_LTO_NO_FAT" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO_COMMON $FLAGS_OPTIM_LTO_PARALLEL" elif flag_enabled "lto-fat" "no"; then TARGET_CFLAGS+=" $FLAGS_OPTIM_LTO_NO_PARALLEL $FLAGS_OPTIM_LTO_FAT" TARGET_CXXFLAGS+=" $FLAGS_OPTIM_LTO_NO_PARALLEL $FLAGS_OPTIM_LTO_FAT" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO_COMMON $FLAGS_OPTIM_LTO_NO_PARALLEL" elif flag_enabled "lto" "no"; then TARGET_CFLAGS+=" $FLAGS_OPTIM_LTO_NO_PARALLEL $FLAGS_OPTIM_LTO_NO_FAT" TARGET_CXXFLAGS+=" $FLAGS_OPTIM_LTO_NO_PARALLEL $FLAGS_OPTIM_LTO_NO_FAT" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO_COMMON $FLAGS_OPTIM_LTO_NO_PARALLEL" fi fi if flag_enabled "lto-off" "no"; then TARGET_CFLAGS+=" $FLAGS_OPTIM_LTO_OFF" TARGET_CXXFLAGS+=" $FLAGS_OPTIM_LTO_OFF" TARGET_LDFLAGS+=" $FLAGS_OPTIM_LTO_OFF" fi # gold flag if flag_enabled "gold" "$GOLD_SUPPORT" "only-disable"; then TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_GOLD" fi # position-independent code if flag_enabled "pic" "no"; then TARGET_CFLAGS+=" $CFLAGS_OPTIM_PIC" TARGET_CXXFLAGS+=" $CXXFLAGS_OPTIM_PIC" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_PIC" fi if flag_enabled "pic:host" "no"; then HOST_CFLAGS+=" $CFLAGS_OPTIM_PIC" HOST_CXXFLAGS+=" $CXXFLAGS_OPTIM_PIC" HOST_LDFLAGS+=" $LDFLAGS_OPTIM_PIC" fi # hardening support if flag_enabled "hardening" "$HARDENING_SUPPORT"; then TARGET_CFLAGS+=" $CFLAGS_OPTIM_HARDENING" TARGET_CXXFLAGS+=" $CXXFLAGS_OPTIM_HARDENING" TARGET_CFLAGS+=" $CPPFLAGS_OPTIM_HARDENING" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_HARDENING" fi # parallel if ! flag_enabled "parallel" "yes"; then NINJA_OPTS="$NINJA_OPTS -j1" export MAKEFLAGS="-j1" else export MAKEFLAGS="-j$CONCURRENCY_MAKE_LEVEL" fi case "$1" in target|init) export DESTIMAGE="target" export CC="${TARGET_PREFIX}gcc" export CXX="${TARGET_PREFIX}g++" export CPP="${TARGET_PREFIX}cpp" export LD="${TARGET_PREFIX}ld" export AS="${TARGET_PREFIX}as" export AR="${TARGET_PREFIX}ar" export NM="${TARGET_PREFIX}nm" export RANLIB="${TARGET_PREFIX}ranlib" export OBJCOPY="${TARGET_PREFIX}objcopy" export OBJDUMP="${TARGET_PREFIX}objdump" export STRIP="${TARGET_PREFIX}strip" export CPPFLAGS="$TARGET_CPPFLAGS" export CFLAGS="$TARGET_CFLAGS" export CXXFLAGS="$TARGET_CXXFLAGS" export LDFLAGS="$TARGET_LDFLAGS" export PKG_CONFIG="$TOOLCHAIN/bin/pkg-config" export PKG_CONFIG_PATH="" export PKG_CONFIG_LIBDIR="$SYSROOT_PREFIX/usr/lib/pkgconfig:$SYSROOT_PREFIX/usr/share/pkgconfig" export PKG_CONFIG_SYSROOT_DIR="$SYSROOT_PREFIX" export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 export CMAKE_CONF=$TOOLCHAIN/etc/cmake-$TARGET_NAME.conf export CMAKE="cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_CONF -DCMAKE_INSTALL_PREFIX=/usr" if [ ! -f $CMAKE_CONF ] ; then mkdir -p $TOOLCHAIN/etc echo "SET(CMAKE_SYSTEM_NAME Linux)" >> $CMAKE_CONF echo "SET(CMAKE_SYSTEM_VERSION 1)" >> $CMAKE_CONF echo "SET(CMAKE_SYSTEM_PROCESSOR $TARGET_ARCH)" >> $CMAKE_CONF echo "SET(CMAKE_C_COMPILER $CC)" >> $CMAKE_CONF echo "SET(CMAKE_CXX_COMPILER $CXX)" >> $CMAKE_CONF echo "SET(CMAKE_CPP_COMPILER $CPP)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH $SYSROOT_PREFIX)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)" >> $CMAKE_CONF fi export HOST_CC="$TOOLCHAIN/bin/host-gcc" export HOST_CXX="$TOOLCHAIN/bin/host-g++" export HOSTCC="$HOST_CC" export HOSTCXX="$HOST_CXX" export CC_FOR_BUILD="$HOST_CC" export CXX_FOR_BUILD="$HOST_CXX" export BUILD_CC="$HOST_CC" export BUILD_CXX="$HOST_CXX" export _python_sysroot="$SYSROOT_PREFIX" export _python_prefix=/usr export _python_exec_prefix=/usr ;; host|bootstrap) export DESTIMAGE="host" export AWK="gawk" export CC="$TOOLCHAIN/bin/host-gcc" export CXX="$TOOLCHAIN/bin/host-g++" export CPP="cpp" export LD="ld" export AS="as" export AR="ar" export NM="nm" export RANLIB="ranlib" export OBJCOPY="objcopy" export OBJDUMP="objdump" export STRIP="strip" export CPPFLAGS="$HOST_CPPFLAGS" export CFLAGS="$HOST_CFLAGS" export CXXFLAGS="$HOST_CXXFLAGS" export LDFLAGS="$HOST_LDFLAGS" export PKG_CONFIG="$TOOLCHAIN/bin/pkg-config" export PKG_CONFIG_PATH="" export PKG_CONFIG_LIBDIR="$TOOLCHAIN/lib/pkgconfig:$TOOLCHAIN/share/pkgconfig" export PKG_CONFIG_SYSROOT_DIR="" unset PKG_CONFIG_ALLOW_SYSTEM_CFLAGS unset PKG_CONFIG_ALLOW_SYSTEM_LIBS export CMAKE_CONF=$TOOLCHAIN/etc/cmake-$HOST_NAME.conf export CMAKE="cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_CONF -DCMAKE_INSTALL_PREFIX=$TOOLCHAIN" if [ ! -f $CMAKE_CONF ] ; then mkdir -p $TOOLCHAIN/etc echo "SET(CMAKE_SYSTEM_NAME Linux)" >> $CMAKE_CONF echo "SET(CMAKE_SYSTEM_VERSION 1)" >> $CMAKE_CONF echo "SET(CMAKE_C_COMPILER $CC)" >> $CMAKE_CONF echo "SET(CMAKE_CXX_COMPILER $CXX)" >> $CMAKE_CONF echo "SET(CMAKE_CPP_COMPILER $CXX)" >> $CMAKE_CONF echo "SET(CMAKE_AR $AR CACHE FILEPATH "Archiver")" >> $CMAKE_CONF # hum? echo "SET(CMAKE_FIND_ROOT_PATH $TOOLCHAIN)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)" >> $CMAKE_CONF echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)" >> $CMAKE_CONF fi export HOST_CC="$CC" export HOST_CXX="$CXX" export HOSTCC="$CC" export HOSTCXX="$CXX" export CC_FOR_BUILD="$CC" export CXX_FOR_BUILD="$CXX" export BUILD_CC="$CC" export BUILD_CXX="$CXX" export _python_sysroot="$TOOLCHAIN" export _python_prefix=/ export _python_exec_prefix=/ ;; esac } create_meson_conf() { local endian root case "$1" in target|init) endian="little" root="$SYSROOT_PREFIX/usr" ;; host|bootstrap) endian="big" root="$TOOLCHAIN" ;; esac cat > $2 <&2 echo -e "$_ALL_DIRS" >&2 exit 1 fi echo "$_PKG_DIR" } # get variable ($2) for package ($1). # avoid infinite recursion if required package is already loaded. get_pkg_variable() { if [ -n "$1" -a -n "$2" ] ; then if [ "$1" != "$PKG_NAME" ]; then cd $ROOT . config/options $1 &>/dev/null fi echo "${!2}" fi } calculate_stamp() { local stamp stamp="$PKG_DIR $PROJECT_DIR/$PROJECT/patches/$PKG_NAME" [ -n "$DEVICE" ] && stamp+=" $PROJECT_DIR/$PROJECT/devices/$DEVICE/patches/$PKG_NAME" [ -n "$PKG_NEED_UNPACK" ] && stamp+=" $PKG_NEED_UNPACK" find ${stamp} -exec sha256sum {} \; 2>/dev/null | sed "s/ ${ROOT//\//\\/}\// /" | sort | sha256sum | cut -d" " -f1 } # return 0 if $2 in space-separated list $1, otherwise return 1 listcontains() { if [ -n "$1" -a -n "$2" ]; then [[ ${1} =~ (^|[[:space:]])${2}($|[[:space:]]) ]] && return 0 || return 1 else return 1 fi } # remove item(s) from list. # looping makes it greedy (eg. removefromlist "abc def ghi" "(abc|def)" will work). listremoveitem() { local data="${1}" odata tmp_array if [ -n "$1" -a -n "$2" ]; then while [ : ]; do odata="${data}" data="$(echo "${data}" | sed -E "s (^|[[:space:]])${2}($|[[:space:]]) \ g")" [ "${odata}" = "${data}" ] && break done fi # Use array word splitting to squash spaces tmp_array=(${data}) echo "${tmp_array[@]}" } # check if a flag is enabled # $1: flag-name, $2: default (yes/no), $3: ingenious check (none,only-disable,only-enable) # set variable PKG_[FLAG]_[HOST/TARGET]_ENABLED=(yes/no) # return 0 if flag is enabled, otherwise 1 flag_enabled() { # make flag name upper case and replace hyphen with underscore, to use as variable name local flag_name=${1^^} [[ $flag_name =~ : ]] || flag_name+="_TARGET" flag_name="PKG_${flag_name//[:-]/_}_ENABLED" # check flag if [ -n "${PKG_BUILD_FLAGS}" ] && listcontains "${PKG_BUILD_FLAGS}" "[+]?$1"; then if [ "${3:none}" = "only-disable" ]; then echo "ERROR: $1 can not enable via PKG_BUILD_FLAGS (found in $PKG_NAME)" exit 1 fi declare ${flag_name}="yes" return 0 elif [ "$2" = "yes" ] && ! listcontains "${PKG_BUILD_FLAGS}" "-$1"; then declare ${flag_name}="yes" return 0 else if [ "${3:none}" = "only-enable" ]; then echo "ERROR: $1 can not disable via PKG_BUILD_FLAGS (found in $PKG_NAME)" exit 1 fi declare ${flag_name}="no" return 1 fi } target_has_feature() { listcontains "$TARGET_FEATURES" "$1" } # find path for matching file or directory, searching standard directory hierarchy, using optional default # if a path is located it will be set in FOUND_PATH and exit code will be 0. find_path() { local test_func="$1" search="$2" default="$3" local dir match wildcard=0 ftype # support wildcard matches [[ $search =~ \* || $search =~ \? ]] && wildcard=1 [ "$test_func" = "-f" ] && ftype="file" || ftype="dir" for dir in $PROJECT_DIR/$PROJECT/devices/$DEVICE/packages/$PKG_NAME \ $PROJECT_DIR/$PROJECT/devices/$DEVICE \ $PROJECT_DIR/$PROJECT/packages/$PKG_NAME \ $PROJECT_DIR/$PROJECT \ $DISTRO_DIR/$DISTRO/packages/$PKG_NAME \ $DISTRO_DIR/$DISTRO \ $PKG_DIR \ ; do # ignore directories with missing DEVICE or PKG_NAME components [[ $dir =~ /packages/$ ]] && continue [[ $dir =~ /devices/$ ]] && continue [[ $dir =~ /devices//packages/$PKG_NAME$ ]] && continue if [ $wildcard -eq 1 ]; then ls $dir/$search 1>/dev/null 2>&1 && match="$dir/$search" && break else [ $test_func "$dir/$search" ] && match="$dir/$search" && break fi done if [ -z "$match" -a -n "$default" ]; then if [[ $default =~ \* || $default =~ \? ]]; then ls $default 1>/dev/null 2>&1 && match="$default" else [ $test_func "$default" ] && match="$default" fi fi if [ -n "$match" ]; then FOUND_PATH="$match" [ "${VERBOSE_FIND_PATH,,}" = "yes" ] && echo "find_path: Searching for $ftype: \"$search\", found: \"$FOUND_PATH\"" >&2 return 0 else unset FOUND_PATH [ "${VERBOSE_FIND_PATH,,}" = "yes" ] && echo "find_path: Searching for $ftype: \"$search\" - not found" >&2 return 1 fi } find_file_path() { find_path -f "$1" "$2" } find_dir_path() { find_path -d "$1" "$2" } set_debug_depends() { local pkg dep_pkg map tmp_array mpkg bpkg kvpair _DEBUG_DEPENDS_LIST="" _DEBUG_PACKAGE_LIST="" if [ "${DEBUG:-no}" != "no" ]; then # Convert DEBUG_GROUPS into array of groups, adding "all" if required declare -A debug_group_map for kvpair in ${DEBUG_GROUPS}; do debug_group_map+=(["${kvpair%=*}"]="${kvpair#*=}") done [ -z "${debug_group_map["all"]}" ] && debug_group_map+=(["all"]="all") # Expand $DEBUG into $_DEBUG_PACKAGE_LIST for pkg in ${DEBUG//,/ }; do [ "${pkg}" = "yes" ] && pkg="${DEBUG_GROUP_YES:-all}" map="${debug_group_map["${pkg}"]}" [ -z "${map}" ] && map="${pkg}" for mpkg in ${map//,/ }; do [[ ${mpkg} =~ ^[!-] ]] && bpkg="${mpkg:1}" || bpkg="${mpkg}" [[ ${bpkg} =~ \+$ ]] && bpkg="${bpkg::-1}" # Remove existing instances of this package listcontains "${_DEBUG_PACKAGE_LIST}" "[!-]?${bpkg}[+]?" && _DEBUG_PACKAGE_LIST="$(listremoveitem "${_DEBUG_PACKAGE_LIST}" "[!-]?${bpkg}[+]?")" # Add package _DEBUG_PACKAGE_LIST+=" ${mpkg}" done done # Use array word splitting to squash spaces tmp_array=(${_DEBUG_PACKAGE_LIST}) _DEBUG_PACKAGE_LIST="${tmp_array[@]}" # Determine dependencies for each package+ for pkg in ${_DEBUG_PACKAGE_LIST}; do if [ "${pkg}" != "all" ] && [[ ! ${pkg} =~ ^[!-] ]]; then ! listcontains "${_DEBUG_DEPENDS_LIST}" "${pkg}" && _DEBUG_DEPENDS_LIST+=" ${pkg}" [[ ! ${pkg} =~ \+$ ]] && continue for dep_pkg in $(get_pkg_variable ${pkg::-1} PKG_DEPENDS_TARGET); do [ "${dep_pkg}" = "toolchain" ] && continue [[ ${dep_pkg} =~ ^.*:host$ ]] && continue ! listcontains "${_DEBUG_DEPENDS_LIST}" "${dep_pkg}" && _DEBUG_DEPENDS_LIST+=" ${dep_pkg}" done fi done tmp_array=(${_DEBUG_DEPENDS_LIST}) _DEBUG_DEPENDS_LIST="${tmp_array[@]}" fi export _DEBUG_DEPENDS_LIST _DEBUG_PACKAGE_LIST } # Return 0 if building with debug is enabled for the current package (or all packages). # Examples: DEBUG=yes DEBUG=all DEBUG='all,!linux' DEBUG=kodi DEBUG=kodi,samba build_with_debug() { if [ "${DEBUG:-no}" != "no" -a -n "${PKG_NAME}" -a -n "${_DEBUG_DEPENDS_LIST+x}" ]; then # Return 1 if this package is not to be built with debug listcontains "${_DEBUG_PACKAGE_LIST}" "[!-]${PKG_NAME}[+]?" && return 1 # Build all packages with debug listcontains "${_DEBUG_PACKAGE_LIST}" "all" && return 0 # Debugging is enabled for at least one package, so enable debug in the "debug" virtual package [ "${PKG_NAME}" = "debug" ] && return 0 # Build addons with debug if we're building the mediacenter with debug and with dependencies [ "${PKG_IS_ADDON}" = "yes" -o "${PKG_IS_ADDON}" = "embedded" ] && listcontains "${_DEBUG_DEPENDS_LIST}" "${MEDIACENTER}\+" && return 0 # Build kernel packages with debug if we're building the kernel with debug and with dependencies [ "${PKG_IS_KERNEL_PKG}" = "yes" ] && listcontains "${_DEBUG_DEPENDS_LIST}" "linux\+" && return 0 # Build this package with debug if it's a resolved dependency listcontains "${_DEBUG_DEPENDS_LIST}" "${PKG_NAME}" && return 0 fi return 1 } install_binary_addon() { local addon_id="$1" addon_so mkdir -p $ADDON_BUILD/$addon_id/ cp -R $PKG_BUILD/.install_pkg/usr/share/$MEDIACENTER/addons/$addon_id/* $ADDON_BUILD/$addon_id/ addon_so=$(xmlstarlet sel -t -v "/addon/extension/@library_linux" $ADDON_BUILD/$addon_id/addon.xml || :) if [ -n "$addon_so" ]; then cp -L $PKG_BUILD/.install_pkg/usr/lib/$MEDIACENTER/addons/$addon_id/$addon_so $ADDON_BUILD/$addon_id/ chmod +x $ADDON_BUILD/$addon_id/$addon_so fi if [ -d $PKG_BUILD/.install_pkg/usr/lib/kernel-overlays/$addon_id ] ; then mkdir -p $ADDON_BUILD/$addon_id/kernel-overlay cp -PR $PKG_BUILD/.install_pkg/usr/lib/kernel-overlays/$addon_id/* $ADDON_BUILD/$addon_id/kernel-overlay fi } install_addon_source() { if [ -d $PKG_DIR/source ]; then cp -R $PKG_DIR/source/* "$1" fi } install_addon_images() { local dest_dir="$1" if [ -f "$PKG_DIR/icon/icon.png" ]; then mkdir -p "$dest_dir/resources" cp "$PKG_DIR/icon/icon.png" "$dest_dir/resources" fi if [ -f "$DISTRO_DIR/$DISTRO/addons/fanart.png" ]; then mkdir -p "$dest_dir/resources" cp "$DISTRO_DIR/$DISTRO/addons/fanart.png" "$dest_dir/resources" fi } create_addon_xml() { local addon_xml addon_version addon_name provider_name requires requires_addonname requires_addonversion screenshots addon_xml="$1/addon.xml" IFS=" " for i in $PKG_ADDON_REQUIRES; do requires_addonname=`echo $i | cut -f1 -d ":"` requires_addonversion=`echo $i | cut -f2 -d ":"` requires="$requires\n " done unset IFS if [ ! -f "$addon_xml" ] ; then cp $ROOT/config/addon/${PKG_ADDON_TYPE}.xml "$addon_xml" addon_version=${PKG_ADDON_VERSION:-${ADDON_VERSION}.${PKG_REV}} else if [ ! $(which xmlstarlet) ]; then echo "*** ERROR: $ADDON has addon.xml shipped, you need 'xmlstarlet' ***" exit 255 fi addon_version="${PKG_ADDON_VERSION:-$(xmlstarlet sel -t -v "/addon/@version" "$addon_xml").$PKG_REV}" xmlstarlet ed --inplace -u "/addon[@version]/@version" -v "$addon_version" "$addon_xml" fi if [ -f $PKG_DIR/changelog.txt ]; then sed -e "/@PKG_ADDON_NEWS@/ \ { r $PKG_DIR/changelog.txt d }" -i "$addon_xml" else sed -e "s|@PKG_ADDON_NEWS@||g" -i "$addon_xml" fi provider_name=${PKG_MAINTAINER:-"Team LibreELEC"} addon_name=${PKG_ADDON_NAME:-"$PKG_NAME"} for f in $PKG_DIR/source/resources/screenshot-*.{jpg,png}; do if [ -f "$f" ]; then screenshots+="resources/$(basename $f)\n" fi done $SED -e "s|@PKG_ADDON_ID@|$PKG_ADDON_ID|g" \ -e "s|@ADDON_NAME@|$addon_name|g" \ -e "s|@ADDON_VERSION@|$addon_version|g" \ -e "s|@REQUIRES@|$requires|g" \ -e "s|@PKG_SHORTDESC@|$PKG_SHORTDESC|g" \ -e "s|@OS_VERSION@|$OS_VERSION|g" \ -e "s|@PKG_LONGDESC@|$PKG_LONGDESC|g" \ -e "s|@PKG_DISCLAIMER@|$PKG_DISCLAIMER|g" \ -e "s|@PROVIDER_NAME@|$provider_name|g" \ -e "s|@PKG_ADDON_PROVIDES@|$PKG_ADDON_PROVIDES|g" \ -e "s|@PKG_ADDON_SCREENSHOT@|$screenshots|g" \ -e "s|@PKG_ADDON_BROKEN@|$PKG_ADDON_BROKEN|g" \ -i "$addon_xml" } install_driver_addon_files() { if [ "$#" -eq 0 ] ; then printf "$(print_color CLR_ERROR "no module search path defined")\n" exit 1 fi PKG_MODULE_DIR="$INSTALL/$(get_full_module_dir $PKG_ADDON_ID)/updates/$PKG_ADDON_ID" PKG_ADDON_DIR="$INSTALL/usr/share/$MEDIACENTER/addons/$PKG_ADDON_ID" mkdir -p $PKG_MODULE_DIR find $@ -name \*.ko -exec cp {} $PKG_MODULE_DIR \; find $PKG_MODULE_DIR -name \*.ko -exec ${TARGET_KERNEL_PREFIX}strip --strip-debug {} \; mkdir -p $PKG_ADDON_DIR cp $PKG_DIR/changelog.txt $PKG_ADDON_DIR install_addon_files "$PKG_ADDON_DIR" } install_addon_files() { install_addon_source "$1" install_addon_images "$1" create_addon_xml "$1" } tolower() { echo "$@" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz } require_eglibc() { if [ "$TARGET_LIBC" != eglibc ]; then echo "$1 requires eglibc, aborting." exit 1 fi } add_user() { # Usage: add_user "username" "password" "userid" "groupid" "description" "home" "shell" mkdir -p ${INSTALL}/etc touch ${INSTALL}/etc/passwd if ! grep -q "^$1:" ${INSTALL}/etc/passwd; then echo "$1:x:$3:$4:$5:$6:$7" >> ${INSTALL}/etc/passwd fi mkdir -p ${INSTALL}/usr/cache touch ${INSTALL}/usr/cache/shadow ln -sf /storage/.cache/shadow ${INSTALL}/etc/shadow PASSWORD="$2" if [ "$PASSWORD" = "x" ]; then PASSWORD="*" fi if ! grep -q "^$1:" ${INSTALL}/usr/cache/shadow; then echo "$1:$PASSWORD:::::::" >> ${INSTALL}/usr/cache/shadow fi } add_group() { # Usage: add_group "groupname" "groupid" ("members") mkdir -p ${INSTALL}/etc touch ${INSTALL}/etc/group if [ -z "`grep "$1:" ${INSTALL}/etc/group`" ]; then echo "$1:x:$2:$3" >> ${INSTALL}/etc/group fi } do_autoreconf() { export ACLOCAL_DIR=$SYSROOT_PREFIX/usr/share/aclocal if [ -e "$TOOLCHAIN/bin/autoconf" ]; then export AUTOCONF=$TOOLCHAIN/bin/autoconf fi if [ -e "$TOOLCHAIN/bin/automake" ]; then export AUTOMAKE=$TOOLCHAIN/bin/automake fi if [ -e "$TOOLCHAIN/bin/autopoint" ]; then export AUTOPOINT=$TOOLCHAIN/bin/autopoint fi if [ -e "$TOOLCHAIN/bin/libtoolize" ]; then export LIBTOOLIZE=$TOOLCHAIN/bin/libtoolize fi if [ -e "$TOOLCHAIN/bin/intltoolize" ]; then export INTLTOOLIZE=$TOOLCHAIN/bin/intltoolize fi if [ -e "$TOOLCHAIN/bin/aclocal" ]; then export ACLOCAL="$TOOLCHAIN/bin/aclocal -I $ACLOCAL_DIR" fi if [ -e "$TOOLCHAIN/bin/autoheader" ]; then export AUTOHEADER=$TOOLCHAIN/bin/autoheader fi if [ -e "$TOOLCHAIN/bin/libtool" ]; then export LIBTOOL=$TOOLCHAIN/bin/libtool fi if [ -e "$TOOLCHAIN/bin/autoreconf" -a -e "$INTLTOOLIZE" ]; then mkdir -p $ACLOCAL_DIR if [ -e "$LIBTOOLIZE" ]; then export AUTORECONF="$TOOLCHAIN/bin/autoreconf --verbose --force --install -I $ACLOCAL_DIR" else export AUTORECONF="$TOOLCHAIN/bin/autoreconf --verbose --force -I $ACLOCAL_DIR" fi $AUTORECONF $@ fi } fix_module_depends() { # modify .modinfo section in kernel module to depends on other required modules local MODULE="$1" local DEPENDS="$2" local OLD_DEPENDS="" cp ${MODULE} ${MODULE}_orig $OBJDUMP -s -j .modinfo ${MODULE}_orig | awk 'BEGIN{v=0;} /Contents/ {v=1; next;} {if (v==1) print $0;}' >new.modinfo1 cat new.modinfo1 | cut -c7-41 | awk '{printf($0);}' | sed 's/ //g;s/../\\\x&/g;' >new.modinfo2 /bin/echo -ne `cat new.modinfo2` | tr '\000' '\n' >new.modinfo3 cat new.modinfo3 | awk '/^depends=/ {next;} {print $0;}' | tr '\n' '\000' >new.modinfo OLD_DEPENDS=$(awk '{FS="="} /depends=/ {print $2}' new.modinfo3) [ -n "$OLD_DEPENDS" ] && DEPENDS="$OLD_DEPENDS,$DEPENDS" /bin/echo -ne "depends=$DEPENDS\0" >>new.modinfo $OBJCOPY --remove-section=.modinfo --add-section=.modinfo=new.modinfo --set-section-flags .modinfo=contents,alloc,load,readonly,data ${MODULE}_orig ${MODULE} rm new.modinfo* } # Usage: enable_service [target] enable_service () { local unit="$1" local unit_dir="/usr/lib/systemd/system" local target="$2" local target_dir=$INSTALL [ -f "$target_dir/$unit_dir/$unit" ] || exit 1 if [ -z "$target" ] ; then for target in `grep '^WantedBy' $target_dir/$unit_dir/$unit | cut -f2 -d=` ; do if [ -n "$target" ]; then mkdir -p ${target_dir}/$unit_dir/${target}.wants ln -sf ../${unit} ${target_dir}/$unit_dir/${target}.wants/ fi done fi for target in `grep '^Alias' $target_dir/$unit_dir/$unit | cut -f2 -d=` ; do if [ -n "$target" ]; then ln -sf ${unit} ${target_dir}/$unit_dir/${target} fi done } init_package_cache() { local _ANCHOR="@?+?@" DIR # If the package caches are unset, then populate them if [ -z "${_CACHE_PACKAGE_LOCAL}" -o -z "${_CACHE_PACKAGE_GLOBAL}" ]; then _CACHE_PACKAGE_LOCAL="${BUILD}/.cache_package_local" _CACHE_PACKAGE_GLOBAL="${BUILD}/.cache_package_global" mkdir -p "${BUILD}" : > "${_CACHE_PACKAGE_LOCAL}" : > "${_CACHE_PACKAGE_GLOBAL}" # cache project/device folder for a package if [ -n $DEVICE ]; then for DIR in $(find $ROOT/projects/$PROJECT/devices/$DEVICE/packages -type d 2>/dev/null); do [ -r "$DIR/package.mk" ] && echo "${DIR}${_ANCHOR}" >> "${_CACHE_PACKAGE_LOCAL}" done fi # cache project folder for a package for DIR in $(find $ROOT/projects/$PROJECT/packages -type d 2>/dev/null); do [ -r "$DIR/package.mk" ] && echo "${DIR}${_ANCHOR}" >> "${_CACHE_PACKAGE_LOCAL}" done # cache packages folder for DIR in $(find $ROOT/$PACKAGES -type d 2>/dev/null); do [ -r "$DIR/package.mk" ] && echo "${DIR}${_ANCHOR}" >> "${_CACHE_PACKAGE_GLOBAL}" done export _CACHE_PACKAGE_LOCAL _CACHE_PACKAGE_GLOBAL fi } check_path() { dashes="===========================" if [ "${PWD##/usr}" != "${PWD}" ]; then check_pathmessage="$check_pathmessage\n $dashes$dashes$dashes" check_pathmessage="$check_pathmessage\n ERROR: You try to build inside /usr" check_pathmessage="$check_pathmessage\n $dashes$dashes$dashes" check_pathmessage="$check_pathmessage\n This is not supported with our buildsystem." check_pathmessage="$check_pathmessage\n Please use another dir (for example your \$HOME) to build $DISTRONAME" echo -e $check_pathmessage exit 1 fi } load_build_config() { if [ -d "${1}" -a -f ${1}/.build.conf ]; then source ${1}/.build.conf return 0 fi return 1 } save_build_config() { local var mkdir -p ${BUILD} rm -f ${BUILD}/.build.conf for var in PROJECT DEVICE ARCH DEBUG BUILD_SUFFIX; do echo "export ${var}=\"${!var}\"" >> ${BUILD}/.build.conf done } check_config() { dashes="===========================" if [ ! -d $PROJECT_DIR/$PROJECT ]; then check_project="$check_project\n $dashes$dashes$dashes" check_project="$check_project\n ERROR: Project not found, use a valid project or create a new config" check_project="$check_project\n $dashes$dashes$dashes" check_project="$check_project\n\n Valid projects:" for projects in $PROJECT_DIR/*; do check_project="$check_project\n - $(basename $projects)" done echo -e $check_project exit 1 fi if [ \( -z "$DEVICE" -a -d "$PROJECT_DIR/$PROJECT/devices" \) -o \( -n "$DEVICE" -a ! -d "$PROJECT_DIR/$PROJECT/devices/$DEVICE" \) ]; then check_device="$check_device\n $dashes$dashes$dashes" check_device="$check_device\n ERROR: You need to specify a valid device for the $PROJECT project" check_device="$check_device\n $dashes$dashes$dashes" check_device="$check_device\n\n Valid devices for project: $PROJECT" for device in $PROJECT_DIR/$PROJECT/devices/*; do check_device="$check_device\n - $(basename $device)" done echo -e $check_device exit 1 fi if [ -d $PROJECT_DIR/$PROJECT/devices/$DEVICE/linux ]; then linux_config_dir="$PROJECT_DIR/$PROJECT/devices/$DEVICE/linux" else linux_config_dir="$PROJECT_DIR/$PROJECT/linux" fi if [ ! -e $linux_config_dir/linux.${TARGET_PATCH_ARCH:-$TARGET_ARCH}.conf ] && ! ls $linux_config_dir/*/linux.${TARGET_PATCH_ARCH:-$TARGET_ARCH}.conf &>/dev/null; then check_arch="$check_arch\n $dashes$dashes$dashes" check_arch="$check_arch\n ERROR: Architecture not found, use a valid Architecture" check_arch="$check_arch\n for your project or create a new config" check_arch="$check_arch\n $dashes$dashes$dashes" check_arch="$check_arch\n\n Valid Architectures for your project: $PROJECT" for arch in $linux_config_dir/*.conf $linux_config_dir/*/linux.$TARGET_ARCH.conf; do [[ ${arch} =~ .*\*.* ]] && continue #ignore unexpanded wildcard check_arch="$check_arch\n - $(basename $arch | cut -f2 -d".")" done echo -e $check_arch exit 1 fi } # strip debug_strip() { if [ -z "${BUILD_WITH_DEBUG}" ]; then echo "ERROR: debug_strip() must not be called without configuring BUILD_WITH_DEBUG" >&2 exit 1 fi if [ "${BUILD_WITH_DEBUG}" != "yes" ] && flag_enabled "strip" "yes"; then find $* -type f -executable | xargs $STRIP 2>/dev/null || : fi } print_color() { local clr_name="$1" clr_text="$2" clr_actual if [ "$DISABLE_COLORS" = "yes" ]; then [ $# -eq 2 ] && echo -en "${clr_text}" return 0 fi clr_actual="${!clr_name}" # If $clr_name isn't another colour variable (boldgreen etc.), then # assume it's an actual colour escape sequence. # # Otherwise if $clr_name isn't defined, or doesn't exist, then use # standard colours. # if [[ -n "${clr_actual}" ]] && [[ -z "${!clr_actual}" ]]; then clr_actual="${clr_name}" elif [[ -z "${clr_actual}" ]] || [[ -z "${!clr_actual}" ]]; then case "${clr_name}" in CLR_ERROR) clr_actual="boldred";; CLR_WARNING) clr_actual="boldred";; CLR_WARNING_DIM) clr_actual="red";; CLR_APPLY_PATCH) clr_actual="boldgreen";; CLR_AUTORECONF) clr_actual="boldmagenta";; CLR_BUILD) clr_actual="boldyellow";; CLR_TOOLCHAIN) clr_actual="boldmagenta";; CLR_CLEAN) clr_actual="boldred";; CLR_FIXCONFIG) clr_actual="boldyellow";; CLR_GET) clr_actual="boldcyan";; CLR_INFO) clr_actual="boldgreen";; CLR_INSTALL) clr_actual="boldgreen";; CLR_PATCH_DESC) clr_actual="boldwhite";; CLR_TARGET) clr_actual="boldwhite";; CLR_UNPACK) clr_actual="boldcyan";; CLR_ENDCOLOR) clr_actual="endcolor";; *) clr_actual="endcolor";; esac fi if [ $# -eq 2 ]; then echo -en "${!clr_actual}${clr_text}${endcolor}" else echo -en "${!clr_actual}" fi } # Use distribution functions if any if [ -f "distributions/$DISTRO/config/functions" ]; then . distributions/$DISTRO/config/functions fi