diff --git a/config/functions b/config/functions index 7b6a2b1e72..d525e7e17e 100644 --- a/config/functions +++ b/config/functions @@ -250,7 +250,38 @@ get_pkg_version() { } get_pkg_directory() { - get_pkg_variable "$1" PKG_DIR + 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) @@ -271,6 +302,22 @@ listcontains() { 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[@]}" +} + target_has_feature() { listcontains "$TARGET_FEATURES" "$1" } @@ -333,6 +380,79 @@ 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 @@ -698,7 +818,12 @@ check_config() { # strip debug_strip() { - if [ ! "$DEBUG" = yes ]; then + 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 } diff --git a/config/optimize b/config/optimize index d4a596d3c7..e75be6011d 100644 --- a/config/optimize +++ b/config/optimize @@ -10,7 +10,7 @@ if [ "$GOLD_SUPPORT" = yes ];then LD_OPTIM_GOLD="-fuse-ld=gold" fi -if [ "$DEBUG" = yes ]; then +if [ "${BUILD_WITH_DEBUG}" = "yes" ]; then TARGET_CFLAGS="$TARGET_CFLAGS -ggdb" TARGET_CXXFLAGS="$TARGET_CXXFLAGS -ggdb" TARGET_LDFLAGS="$TARGET_LDFLAGS -ggdb" diff --git a/config/options b/config/options index 865c6ed7d8..e432f1e560 100644 --- a/config/options +++ b/config/options @@ -109,6 +109,8 @@ if [ "$OEM" = yes -o "$OEM" = no ]; then OEM_SUPPORT=$OEM fi +[ -z ${_DEBUG_DEPENDS_LIST+x} ] && set_debug_depends + check_path >&2 check_config >&2 diff --git a/config/path b/config/path index fcca196b45..e6821b9d93 100644 --- a/config/path +++ b/config/path @@ -52,48 +52,20 @@ SED="sed -i" unset LD_LIBRARY_PATH +# Don't use BUILD_WITH_DEBUG in "gloabl" package.mk - instead, call the function +# build_with_debug() directly as the function depends on various package.mk +# variables that will be in the process of being configured. Once package.mk is +# fully sourced we can set this variable and use it in situations where we know the +# package has already been sourced. +unset BUILD_WITH_DEBUG + # If the package caches are unset, then populate them init_package_cache # set package metadata reset_pkg_vars "$1" -if [ -n "$1" ]; then - _PKG_ROOT_NAME=${1%:*} - _ALL_DIRS="" - _FOUND=0 - _ANCHOR="@?+?@" - PKG_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:" - echo -e "$_ALL_DIRS" - exit 1 - fi -fi +[ -n "$1" ] && PKG_DIR="$(get_pkg_directory $1)" if [ -n "$PKG_DIR" -a -r $PKG_DIR/package.mk ]; then unset -f configure_package @@ -141,6 +113,8 @@ fi PKG_BUILD="$BUILD/${PKG_NAME}-${PKG_VERSION}" +build_with_debug && BUILD_WITH_DEBUG="yes" || BUILD_WITH_DEBUG="no" + XORG_PATH_DRI=/usr/lib/dri XORG_PATH_XKB=/usr/share/X11/xkb XORG_PATH_XKB_OUTPUT=/var/lib/xkb diff --git a/config/show_config b/config/show_config index 3de77b49e5..985bc89538 100644 --- a/config/show_config +++ b/config/show_config @@ -19,6 +19,7 @@ show_config() { config_message="$config_message\n - LTO (Link Time Optimization) support: $LTO_SUPPORT" config_message="$config_message\n - GOLD (Google Linker) Support:\t $GOLD_SUPPORT" config_message="$config_message\n - LLVM support:\t\t\t $LLVM_SUPPORT" + config_message="$config_message\n - DEBUG:\t\t\t\t ${DEBUG:-no}" # config_message="$config_message\n - CFLAGS:\t $TARGET_CFLAGS" # config_message="$config_message\n - LDFLAGS:\t $TARGET_LDFLAGS" diff --git a/distributions/LibreELEC/options b/distributions/LibreELEC/options index 581141a95e..44c63abf09 100644 --- a/distributions/LibreELEC/options +++ b/distributions/LibreELEC/options @@ -200,3 +200,7 @@ SYSTEM_SIZE=512 # Default system partition offset, in sectors, eg. 2048 SYSTEM_PART_START=8192 + +# Configure debug groups (space delimited key=value pairs, with each value comma-delimited) and default group when DEBUG=yes + DEBUG_GROUPS="kodi=kodi,kodi-platform,p8-platform,!mesa" + DEBUG_GROUP_YES="kodi" diff --git a/packages/audio/alsa-lib/package.mk b/packages/audio/alsa-lib/package.mk index c21db4ceaa..7110dfd95a 100644 --- a/packages/audio/alsa-lib/package.mk +++ b/packages/audio/alsa-lib/package.mk @@ -29,7 +29,7 @@ PKG_SHORTDESC="alsa-lib: Advanced Linux Sound Architecture library" PKG_LONGDESC="ALSA (Advanced Linux Sound Architecture) is the next generation Linux Sound API. It provides much finer (->better) access to the sound hardware, has a unbeatable mixer API and supports stuff like multi channel hardware, digital outs and ins, uninterleaved sound data access, and an oss emulation layer (for the old applications). It is the prefered API for professional sound apps under Linux." PKG_TOOLCHAIN="autotools" -if [ "$DEBUG" = yes ]; then +if build_with_debug; then ALSA_DEBUG=--with-debug else ALSA_DEBUG=--without-debug diff --git a/packages/databases/mysql/package.mk b/packages/databases/mysql/package.mk index ae4f5eedc2..02bcfe7234 100644 --- a/packages/databases/mysql/package.mk +++ b/packages/databases/mysql/package.mk @@ -55,7 +55,7 @@ PKG_CMAKE_OPTS_HOST="-DCMAKE_BUILD_TYPE=Release \ -DWITH_UNIT_TESTS=OFF \ -DWITH_ZLIB=bundled" -if [ "$DEBUG" = yes -a "$TARGET_ARCH" = aarch64 ]; then +if build_with_debug && [ "$TARGET_ARCH" = aarch64 ]; then pre_configure_target() { strip_lto } diff --git a/packages/devel/attr/package.mk b/packages/devel/attr/package.mk index 8ddf6f0e69..c86812fb4f 100644 --- a/packages/devel/attr/package.mk +++ b/packages/devel/attr/package.mk @@ -34,7 +34,7 @@ PKG_CONFIGURE_OPTS_TARGET="OPTIMIZER= \ INSTALL_USER=root INSTALL_GROUP=root \ --disable-shared --enable-static" -if [ "$DEBUG" = yes ]; then +if build_with_debug; then PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET DEBUG=-DDEBUG" else PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET DEBUG=-DNDEBUG" diff --git a/packages/devel/glibc/package.mk b/packages/devel/glibc/package.mk index 1b0d783e02..46b711cb9a 100644 --- a/packages/devel/glibc/package.mk +++ b/packages/devel/glibc/package.mk @@ -53,7 +53,7 @@ PKG_CONFIGURE_OPTS_TARGET="BASH_SHELL=/bin/sh \ --enable-lock-elision \ --disable-timezone-tools" -if [ "$DEBUG" = yes ]; then +if build_with_debug; then PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET --enable-debug" else PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET --disable-debug" diff --git a/packages/lang/gcc/package.mk b/packages/lang/gcc/package.mk index b4862a9a7f..221ec13f1d 100644 --- a/packages/lang/gcc/package.mk +++ b/packages/lang/gcc/package.mk @@ -93,7 +93,7 @@ post_make_host() { rm -rf $TARGET_NAME/libgcc/libgcc_s.so ln -sf libgcc_s.so.1 $TARGET_NAME/libgcc/libgcc_s.so - if [ ! "$DEBUG" = yes ]; then + if [ ! "${BUILD_WITH_DEBUG}" = "yes" ]; then ${TARGET_PREFIX}strip $TARGET_NAME/libgcc/libgcc_s.so* ${TARGET_PREFIX}strip $TARGET_NAME/libstdc++-v3/src/.libs/libstdc++.so* fi diff --git a/packages/multimedia/ffmpeg/package.mk b/packages/multimedia/ffmpeg/package.mk index f74643d7f7..5377b0e95d 100644 --- a/packages/multimedia/ffmpeg/package.mk +++ b/packages/multimedia/ffmpeg/package.mk @@ -47,7 +47,7 @@ else FFMPEG_VDPAU="--disable-vdpau" fi -if [ "$DEBUG" = "yes" ]; then +if build_with_debug; then FFMPEG_DEBUG="--enable-debug --disable-stripping" else FFMPEG_DEBUG="--disable-debug --enable-stripping" diff --git a/packages/network/bluez/package.mk b/packages/network/bluez/package.mk index 5ee2c02add..c39efaaaa8 100644 --- a/packages/network/bluez/package.mk +++ b/packages/network/bluez/package.mk @@ -29,7 +29,7 @@ PKG_SHORTDESC="bluez: Bluetooth Tools and System Daemons for Linux." PKG_LONGDESC="Bluetooth Tools and System Daemons for Linux." PKG_TOOLCHAIN="autotools" -if [ "$DEBUG" = "yes" ]; then +if build_with_debug; then BLUEZ_CONFIG="--enable-debug" else BLUEZ_CONFIG="--disable-debug" diff --git a/packages/virtual/debug/package.mk b/packages/virtual/debug/package.mk index 3acf9a7ee1..8e1d6181d7 100644 --- a/packages/virtual/debug/package.mk +++ b/packages/virtual/debug/package.mk @@ -38,6 +38,6 @@ if [ "$VAAPI_SUPPORT" = "yes" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libva-utils" fi -if [ "$DEBUG" = "yes" -a "$VALGRIND" = "yes" ]; then +if build_with_debug && [ "$VALGRIND" = "yes" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET valgrind" fi diff --git a/scripts/build b/scripts/build index a145f9d431..bb6f2822ee 100755 --- a/scripts/build +++ b/scripts/build @@ -66,6 +66,10 @@ if [ -f $STAMP ] ; then rm -f $STAMP fi + if [ ! "$BUILD_WITH_DEBUG" = "$STAMP_BUILD_WITH_DEBUG" ]; then + rm -f $STAMP + fi + if [ "$1" = "u-boot" -a ! "$UBOOT_SYSTEM" = "$STAMP_UBOOT_SYSTEM" ]; then rm -f $STAMP fi @@ -125,6 +129,15 @@ unset -f pre_makeinstall_bootstrap unset -f makeinstall_bootstrap unset -f post_makeinstall_bootstrap +# configure debug build defaults +if [ "${BUILD_WITH_DEBUG}" = "yes" ]; then + CMAKE_BUILD_TYPE="Debug" + MESON_BUILD_TYPE="debug" +else + CMAKE_BUILD_TYPE="MinSizeRel" + MESON_BUILD_TYPE="plain" +fi + # configure TARGET build defaults TARGET_CONFIGURE_OPTS="--host=$TARGET_NAME \ --build=$HOST_NAME \ @@ -138,13 +151,6 @@ TARGET_CONFIGURE_OPTS="--host=$TARGET_NAME \ --disable-static \ --enable-shared" -# cmake build defaults -if [ "$DEBUG" = "yes" ]; then - CMAKE_BUILD_TYPE="Debug" -else - CMAKE_BUILD_TYPE="MinSizeRel" -fi - CMAKE_GENERATOR_NINJA="-GNinja \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" @@ -152,13 +158,6 @@ TARGET_CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=$CMAKE_CONF \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" -# meson build defaults -if [ "$DEBUG" = "yes" ]; then - MESON_BUILD_TYPE="debug" -else - MESON_BUILD_TYPE="plain" -fi - TARGET_MESON_OPTS="--prefix=/usr \ --bindir=/usr/bin \ --sbindir=/usr/sbin \ @@ -232,13 +231,17 @@ for p in $_pkg_depends; do $SCRIPTS/build $p done -printf "%${BUILD_INDENT}c $(print_color CLR_BUILD "BUILD") $PACKAGE_NAME $(print_color CLR_TARGET "($TARGET)")\n" ' '>&$SILENT_OUT +if [ "${BUILD_WITH_DEBUG}" = "yes" ]; then + printf "%${BUILD_INDENT}c $(print_color CLR_BUILD "BUILD") $PACKAGE_NAME $(print_color CLR_TARGET "($TARGET)") [DEBUG]\n" ' '>&$SILENT_OUT +else + printf "%${BUILD_INDENT}c $(print_color CLR_BUILD "BUILD") $PACKAGE_NAME $(print_color CLR_TARGET "($TARGET)")\n" ' '>&$SILENT_OUT +fi export BUILD_INDENT=$((${BUILD_INDENT:-1}+$BUILD_INDENT_SIZE)) # virtual packages dont must be build, they only contains dependencies, so dont go further here if [ "$PKG_SECTION" = "virtual" ]; then PKG_DEEPMD5=$(find $STAMP_DEPENDS -exec md5sum {} \; 2>/dev/null | sort | md5sum | cut -d" " -f1) - for i in PKG_NAME PKG_DEEPMD5; do + for i in PKG_NAME PKG_DEEPMD5 BUILD_WITH_DEBUG; do echo "STAMP_$i=\"${!i}\"" >> $STAMP done @@ -538,7 +541,7 @@ if [ "$TARGET" = "target" -o "$TARGET" = "init" ]; then -exec rm -f {} \; 2>/dev/null || : find $INSTALL -type d -exec rmdir -p {} \; 2>/dev/null || : - if [ ! "$DEBUG" = yes ]; then + if [ ! "${BUILD_WITH_DEBUG}" = "yes" ]; then $STRIP `find $INSTALL \ -type f -name "*.so*" \ ! -name "ld-*.so" \ @@ -562,7 +565,7 @@ for i in `find $SYSROOT_PREFIX/usr/lib/ -name "*.la" 2>/dev/null`; do \ done PKG_DEEPMD5=$(find $STAMP_DEPENDS -exec md5sum {} \; 2>/dev/null | sort | md5sum | cut -d" " -f1) -for i in PKG_NAME PKG_DEEPMD5; do +for i in PKG_NAME PKG_DEEPMD5 BUILD_WITH_DEBUG; do echo "STAMP_$i=\"${!i}\"" >> $STAMP done diff --git a/scripts/image b/scripts/image index 550d6fb8a8..d56b8258a7 100755 --- a/scripts/image +++ b/scripts/image @@ -18,7 +18,7 @@ # along with OpenELEC. If not, see . ################################################################################ -unset _CACHE_PACKAGE_LOCAL _CACHE_PACKAGE_GLOBAL +unset _CACHE_PACKAGE_LOCAL _CACHE_PACKAGE_GLOBAL _DEBUG_DEPENDS_LIST _DEBUG_PACKAGE_LIST . config/options ""