Skip to content

Instantly share code, notes, and snippets.

@MilhouseVH
Last active May 29, 2018 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MilhouseVH/ac7e46e3c4174b35a1f6a8029775d06e to your computer and use it in GitHub Desktop.
Save MilhouseVH/ac7e46e3c4174b35a1f6a8029775d06e to your computer and use it in GitHub Desktop.
setup_toolchain() {
if [ "$LTO_SUPPORT" = "yes" ]; then
if flag_enabled "lto-fat" "no"; then
TARGET_CFLAGS+=" $CFLAGS_OPTIM_LTO"
TARGET_CXXFLAGS+=" $CXXFLAGS_OPTIM_LTO"
if flag_enabled "lto-parallel" "no"; then
TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO_PARALLEL"
else
TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO"
fi
elif flag_enabled "lto-thin" "no"; then
TARGET_CFLAGS+=" $CFLAGS_OPTIM_LTO_NO_FAT"
TARGET_CXXFLAGS+=" $CXXFLAGS_OPTIM_LTO_NO_FAT"
if flag_enabled "lto-parallel" "no"; then
TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO_PARALLEL"
else
TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_LTO"
fi
fi
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 <<EOF
[binaries]
c = '$CC'
cpp = '$CXX'
ar = '$AR'
strip = '$STRIP'
pkgconfig = '$PKG_CONFIG'
[host_machine]
system = 'linux'
cpu_family = '$TARGET_ARCH'
cpu = '$TARGET_SUBARCH'
endian = '$endian'
[properties]
root = '$root'
$(python -c "import os; print('c_args = {}'.format([x for x in os.getenv('CFLAGS').split()]))")
$(python -c "import os; print('c_link_args = {}'.format([x for x in os.getenv('LDFLAGS').split()]))")
EOF
}
# unset all PKG_* vars apart from those exported by setup_toolchain, then set default values
reset_pkg_vars() {
local vars var
for var in ${!PKG_*}; do
if [ "${var}" = "PKG_CONFIG" ] || \
[ "${var}" = "PKG_CONFIG_PATH" ] || \
[ "${var}" = "PKG_CONFIG_LIBDIR" ] || \
[ "${var}" = "PKG_CONFIG_SYSROOT_DIR" ] || \
[ "${var}" = "PKG_CONFIG_ALLOW_SYSTEM_CFLAGS" ] || \
[ "${var}" = "PKG_CONFIG_ALLOW_SYSTEM_LIBS" ]; then
continue
fi
vars+="${var} "
done
[ -n "${vars}" ] && unset -v ${vars}
PKG_VERSION="0.0invalid"
PKG_REV="0"
PKG_ARCH="any"
PKG_LICENSE="unknown"
PKG_TOOLCHAIN="auto"
PKG_IS_ADDON="no"
PKG_PYTHON_VERSION="python2.7"
}
kernel_path() {
get_build_dir linux
}
kernel_version() {
get_pkg_version linux
}
kernel_config_path() {
local cfg pkg_linux_dir pkg_linux_version config_name
# avoid infinite recursion if this is called by linux
if [ "$PKG_NAME" = "linux" ]; then
pkg_linux_version="$PKG_VERSION"
pkg_linux_dir="$PKG_DIR"
else
pkg_linux_version="$(get_pkg_version linux)"
pkg_linux_dir="$(get_pkg_directory linux)"
fi
config_name="linux.${TARGET_PATCH_ARCH:-$TARGET_ARCH}.conf"
for cfg in $PROJECT_DIR/$PROJECT/devices/$DEVICE/linux/$pkg_linux_version/$config_name \
$PROJECT_DIR/$PROJECT/devices/$DEVICE/linux/$LINUX/$config_name \
$PROJECT_DIR/$PROJECT/devices/$DEVICE/linux/$config_name \
$PROJECT_DIR/$PROJECT/linux/$pkg_linux_version/$config_name \
$PROJECT_DIR/$PROJECT/linux/$LINUX/$config_name \
$PROJECT_DIR/$PROJECT/linux/$config_name \
$pkg_linux_dir/config/$pkg_linux_version/$config_name \
$pkg_linux_dir/config/$LINUX/$config_name \
$pkg_linux_dir/config/$config_name \
; do
[[ $cfg =~ /devices//linux/ ]] && continue
[ -f "$cfg" ] && echo "$cfg" && break
done
}
# get kernel module dir
get_module_dir() {
if [ -n "${_CACHED_KERNEL_MODULE_DIR}" ]; then
echo "${_CACHED_KERNEL_MODULE_DIR}"
else
basename $(ls -d $(get_build_dir linux)/.install_pkg/usr/lib/kernel-overlays/base/lib/modules/*)
fi
}
# get base path to kernel modules and firmware
get_kernel_overlay_dir() {
echo "usr/lib/kernel-overlays/${1:-base}"
}
# get full path to kernel module dir
# optional parameter specifies overlay level (default is base)
get_full_module_dir() {
echo "$(get_kernel_overlay_dir $1)/lib/modules/$(get_module_dir)"
}
# get full path to firmware dir
# optional parameter specifies overlay level (default is base)
get_full_firmware_dir() {
echo "$(get_kernel_overlay_dir $1)/lib/firmware"
}
# get package's build dir
get_build_dir() {
local _PKG_NAME="$(get_pkg_variable "$1" PKG_NAME)" _PKG_VERSION="$(get_pkg_version "$1")"
if [ -n "$_PKG_NAME" -a -n "$_PKG_VERSION" ]; then
echo $BUILD/${_PKG_NAME}-${_PKG_VERSION}
fi
}
get_pkg_version() {
get_pkg_variable "$1" PKG_VERSION
}
get_pkg_directory() {
local _PKG_ROOT_NAME=${1%:*} _ALL_DIRS _FOUND=0 _ANCHOR="@?+?@" _PKG_DIR _DIR
# Check for any available local package in preference to a global package
for _DIR in $(echo -e "${_CACHE_PACKAGE_LOCAL}" | grep -F "/${_PKG_ROOT_NAME}${_ANCHOR}"); do
_DIR="${_DIR%${_ANCHOR}}"
# found first, set $_PKG_DIR
_PKG_DIR="$_DIR"
# keep track of dirs with package.mk for detecting multiple folders
_ALL_DIRS+="${_DIR}\n"
_FOUND=$((_FOUND+1))
done
# If there's no local package available, use the global package
if [ $_FOUND -eq 0 ]; then
for _DIR in $(echo -e "${_CACHE_PACKAGE_GLOBAL}" | grep -F "/${_PKG_ROOT_NAME}${_ANCHOR}"); do
_DIR="${_DIR%${_ANCHOR}}"
# found first, set $_PKG_DIR
_PKG_DIR="$_DIR"
# keep track of dirs with package.mk for detecting multiple folders
_ALL_DIRS+="${_DIR}\n"
_FOUND=$((_FOUND+1))
done
fi
# _FOUND multiple packages? fail
if [ $_FOUND -gt 1 ]; then
echo "Error - multiple package folders for package ${_PKG_ROOT_NAME}:" >&2
echo -e "$_ALL_DIRS" >&2
exit 1
fi
echo "$_PKG_DIR"
}
# get variable ($2) for package ($1)
get_pkg_variable() {
if [ -n "$1" -a -n "$2" ] ; then
cd $ROOT
. config/options $1 &>/dev/null
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}"
# 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}"
for dep_pkg in $(get_pkg_variable ${pkg} 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
[ "${PKG_IS_ADDON}" = "yes" ] && listcontains "${_DEBUG_DEPENDS_LIST}" "${MEDIACENTER}" && return 0
# Build kernel packages with debug if we're building the kernel with debug
[ "${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 <import addon=\"$requires_addonname\" version=\"$requires_addonversion\" />"
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+="<screenshot>resources/$(basename $f)</screenshot>\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 <unit> [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+x}" -o -z "${_CACHE_PACKAGE_GLOBAL+x}" ]; then
_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" ] && _CACHE_PACKAGE_LOCAL+="${DIR}${_ANCHOR}\n"
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" ] && _CACHE_PACKAGE_LOCAL+="${DIR}${_ANCHOR}\n"
done
# cache packages folder
for DIR in $(find $ROOT/$PACKAGES -type d 2>/dev/null); do
[ -r "$DIR/package.mk" ] && _CACHE_PACKAGE_GLOBAL+="${DIR}${_ANCHOR}\n"
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" ]; 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment