diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXcomposite/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXcomposite/package.mk index 724a527e4f..0d391a8a49 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXcomposite/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXcomposite/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXcomposite" PKG_LONGDESC="libXcomposite for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXdamage/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXdamage/package.mk index 477eb2806f..40466578c7 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXdamage/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXdamage/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXdamage" PKG_LONGDESC="libXdamage for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXfixes/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXfixes/package.mk index 91bb174ea0..3faf93c8a9 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXfixes/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXfixes/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXfixes" PKG_LONGDESC="libXfixes for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXi/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXi/package.mk index 6353223655..3dc54ccab6 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXi/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXi/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXi" PKG_LONGDESC="libXi for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXrender/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXrender/package.mk index ad5bb175f6..3cd9ebdd3b 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXrender/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXrender/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXrender" PKG_LONGDESC="libXrender for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libXtst/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libXtst/package.mk index b0f2390b66..12833f9785 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libXtst/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libXtst/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libXtst" PKG_LONGDESC="libXtst for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/chrome-libxcb/package.mk b/packages/addons/addon-depends/chrome-depends/chrome-libxcb/package.mk index 1f4efebfeb..08b0659c38 100644 --- a/packages/addons/addon-depends/chrome-depends/chrome-libxcb/package.mk +++ b/packages/addons/addon-depends/chrome-depends/chrome-libxcb/package.mk @@ -7,15 +7,14 @@ PKG_NAME="chrome-libxcb" PKG_LONGDESC="libxcb for chrome" PKG_URL="" +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --enable-shared" + unpack() { mkdir -p $PKG_BUILD tar --strip-components=1 -xf $SOURCES/${PKG_NAME:7}/${PKG_NAME:7}-$PKG_VERSION.tar.bz2 -C $PKG_BUILD } -PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET \ - --disable-static \ - --enable-shared" - makeinstall_target() { : } diff --git a/packages/addons/addon-depends/chrome-depends/cups/package.mk b/packages/addons/addon-depends/chrome-depends/cups/package.mk index 09e96dde17..1ed87d1ef4 100644 --- a/packages/addons/addon-depends/chrome-depends/cups/package.mk +++ b/packages/addons/addon-depends/chrome-depends/cups/package.mk @@ -12,11 +12,6 @@ PKG_DEPENDS_TARGET="toolchain openssl zlib" PKG_LONGDESC="CUPS printing system." PKG_BUILD_FLAGS="+pic" -pre_configure_target() { - cd .. - rm -rf .$TARGET_NAME -} - PKG_CONFIGURE_OPTS_TARGET="--libdir=/usr/lib \ --disable-gssapi \ --disable-avahi \ @@ -24,6 +19,11 @@ PKG_CONFIGURE_OPTS_TARGET="--libdir=/usr/lib \ --disable-launchd \ --disable-unit-tests" +pre_configure_target() { + cd .. + rm -rf .$TARGET_NAME +} + makeinstall_target() { make BUILDROOT="$INSTALL/../.INSTALL_PKG" } diff --git a/packages/addons/service/hyperion/package.mk b/packages/addons/service/hyperion/package.mk index ecac3d87e4..053ae08e22 100644 --- a/packages/addons/service/hyperion/package.mk +++ b/packages/addons/service/hyperion/package.mk @@ -36,14 +36,6 @@ elif [ "$DISPLAYSERVER" = "x11" ]; then PKG_X11_SUPPORT="-DENABLE_X11=1" fi -pre_build_target() { - cp -a $(get_build_dir rpi_ws281x)/* $PKG_BUILD/dependencies/external/rpi_ws281x -} - -pre_configure_target() { - echo "" > ../cmake/FindGitVersion.cmake -} - PKG_CMAKE_OPTS_TARGET="-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON \ -DHYPERION_VERSION_ID="$PKG_VERSION" \ $PKG_AMLOGIC_SUPPORT \ @@ -61,6 +53,14 @@ PKG_CMAKE_OPTS_TARGET="-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON \ -DENABLE_TESTS=0 \ -Wno-dev" +pre_build_target() { + cp -a $(get_build_dir rpi_ws281x)/* $PKG_BUILD/dependencies/external/rpi_ws281x +} + +pre_configure_target() { + echo "" > ../cmake/FindGitVersion.cmake +} + makeinstall_target() { : # nothing to do here } diff --git a/packages/addons/service/mpd/package.mk b/packages/addons/service/mpd/package.mk index fdb5ee14bd..c9ad40436d 100644 --- a/packages/addons/service/mpd/package.mk +++ b/packages/addons/service/mpd/package.mk @@ -20,10 +20,6 @@ PKG_IS_ADDON="yes" PKG_ADDON_NAME="Music Player Daemon (MPD)" PKG_ADDON_TYPE="xbmc.service" -pre_configure_target() { - export LIBS="$LIBS -logg -lFLAC -ldl" -} - PKG_CONFIGURE_OPTS_TARGET=" \ --enable-aac \ --disable-adplug \ @@ -90,6 +86,10 @@ PKG_CONFIGURE_OPTS_TARGET=" \ --enable-zlib \ --with-zeroconf=no" +pre_configure_target() { + export LIBS="$LIBS -logg -lFLAC -ldl" +} + makeinstall_target() { : } diff --git a/packages/databases/mysql/package.mk b/packages/databases/mysql/package.mk index a91f51d13e..e3c05a9f9c 100644 --- a/packages/databases/mysql/package.mk +++ b/packages/databases/mysql/package.mk @@ -11,15 +11,6 @@ PKG_DEPENDS_HOST="toolchain zlib:host" PKG_DEPENDS_TARGET="toolchain zlib ncurses openssl boost mysql:host" PKG_LONGDESC="A SQL database server." -post_unpack() { - sed -i 's|GET_TARGET_PROPERTY(LIBMYSQL_OS_OUTPUT_NAME libmysql OUTPUT_NAME)|SET(LIBMYSQL_OS_OUTPUT_NAME "mysqlclient")|' $PKG_BUILD/scripts/CMakeLists.txt - sed -i "s|COMMAND comp_err|COMMAND $TOOLCHAIN/bin/comp_err|" $PKG_BUILD/extra/CMakeLists.txt - sed -i "s|COMMAND comp_sql|COMMAND $TOOLCHAIN/bin/comp_sql|" $PKG_BUILD/scripts/CMakeLists.txt - sed -i "s|COMMAND gen_lex_hash|COMMAND $TOOLCHAIN/bin/gen_lex_hash|" $PKG_BUILD/sql/CMakeLists.txt - - sed -i '/^IF(NOT BOOST_MINOR_VERSION.*$/,/^ENDIF()$/d' $PKG_BUILD/cmake/boost.cmake -} - PKG_CMAKE_OPTS_HOST="-DCMAKE_BUILD_TYPE=Release \ -DSTACK_DIRECTION=-1 \ -DHAVE_LLVM_LIBCPP_EXITCODE=0 \ @@ -37,23 +28,6 @@ PKG_CMAKE_OPTS_HOST="-DCMAKE_BUILD_TYPE=Release \ -DWITH_UNIT_TESTS=OFF \ -DWITH_ZLIB=bundled" -make_host() { - ninja comp_err - ninja gen_lex_hash - ninja comp_sql -} - -post_make_host() { - # needed so the binary isn't built for target - cp scripts/comp_sql ../scripts/comp_sql -} - -makeinstall_host() { - cp -P extra/comp_err $TOOLCHAIN/bin - cp -P sql/gen_lex_hash $TOOLCHAIN/bin - cp -P scripts/comp_sql $TOOLCHAIN/bin -} - PKG_CMAKE_OPTS_TARGET="-DINSTALL_INCLUDEDIR=include/mysql \ -DCMAKE_BUILD_TYPE=Release \ -DFEATURE_SET=classic \ @@ -75,6 +49,32 @@ PKG_CMAKE_OPTS_TARGET="-DINSTALL_INCLUDEDIR=include/mysql \ -DSTACK_DIRECTION=1 \ -DHAVE_LLVM_LIBCPP=1" +post_unpack() { + sed -i 's|GET_TARGET_PROPERTY(LIBMYSQL_OS_OUTPUT_NAME libmysql OUTPUT_NAME)|SET(LIBMYSQL_OS_OUTPUT_NAME "mysqlclient")|' $PKG_BUILD/scripts/CMakeLists.txt + sed -i "s|COMMAND comp_err|COMMAND $TOOLCHAIN/bin/comp_err|" $PKG_BUILD/extra/CMakeLists.txt + sed -i "s|COMMAND comp_sql|COMMAND $TOOLCHAIN/bin/comp_sql|" $PKG_BUILD/scripts/CMakeLists.txt + sed -i "s|COMMAND gen_lex_hash|COMMAND $TOOLCHAIN/bin/gen_lex_hash|" $PKG_BUILD/sql/CMakeLists.txt + + sed -i '/^IF(NOT BOOST_MINOR_VERSION.*$/,/^ENDIF()$/d' $PKG_BUILD/cmake/boost.cmake +} + +make_host() { + ninja comp_err + ninja gen_lex_hash + ninja comp_sql +} + +post_make_host() { + # needed so the binary isn't built for target + cp scripts/comp_sql ../scripts/comp_sql +} + +makeinstall_host() { + cp -P extra/comp_err $TOOLCHAIN/bin + cp -P sql/gen_lex_hash $TOOLCHAIN/bin + cp -P scripts/comp_sql $TOOLCHAIN/bin +} + post_makeinstall_target() { sed -i "s|pkgincludedir=.*|pkgincludedir=\'$SYSROOT_PREFIX/usr/include/mysql\'|" scripts/mysql_config sed -i "s|pkglibdir=.*|pkglibdir=\'$SYSROOT_PREFIX/usr/lib/mysql\'|" scripts/mysql_config diff --git a/packages/emulation/libretro-ppsspp/package.mk b/packages/emulation/libretro-ppsspp/package.mk index f25d132eaa..58c42f67ab 100644 --- a/packages/emulation/libretro-ppsspp/package.mk +++ b/packages/emulation/libretro-ppsspp/package.mk @@ -27,14 +27,14 @@ if [ "$PROJECT" = "Amlogic" ] || [ "$PROJECT" = "RPi" ]; then esac fi -pre_configure_target() { - LDFLAGS="$LDFLAGS -lpthread" -} - PKG_CMAKE_OPTS_TARGET="-DLIBRETRO=ON \ -DUSE_SYSTEM_FFMPEG=ON \ $PKG_ARCH_ARM" +pre_configure_target() { + LDFLAGS="$LDFLAGS -lpthread" +} + pre_make_target() { find . -name flags.make -exec sed -i "s:isystem :I:g" \{} \; } diff --git a/packages/readme.md b/packages/readme.md index 89390746f5..f141c19d57 100644 --- a/packages/readme.md +++ b/packages/readme.md @@ -212,7 +212,7 @@ Lastly, the following variables are assigned during `scripts/build` but some pac BOOTSTRAP_MESON_OPTS ``` -###### Example +#### Example ``` configure_package() { # now we know where we're building, assign a value @@ -235,6 +235,19 @@ post_makeinstall_target() { } ``` +#### tools/pkgcheck + +Use `tools/pkgcheck` to verify packages. It detects the following issues: + +Issue | Level | Meaning | +| :--- | :----: | ---- | +| late binding violation | FAIL | Late binding variables referenced outside of a function - see [late binding](https://github.com/LibreELEC/LibreELEC.tv/blob/master/packages/readme.md#late-binding-variable-assignment) | +| duplicate function def | FAIL | Function defined multiple times, only last definition will be used | +| bad func - missing brace | FAIL | Opening brace (`{`) for function definition should be on same line as the function def, ie. `pre_configure_target() {` | +| intertwined vars & funcs | WARN | Variable assignments and logic is intertwined with functions - this is cosmetic, but variables and logic should be specified before all functions | +| unknown function | WARN | Could be a misspelled function, ie. `per_configure_target() {` which might fail silently.| + + ## Add a new package to the Image 1. Think about, why you need it in the image. * new multimedia tool diff --git a/tools/pkgcheck b/tools/pkgcheck new file mode 100755 index 0000000000..53e4b661ad --- /dev/null +++ b/tools/pkgcheck @@ -0,0 +1,158 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +TXRED="$(tput setaf 1 bold)" +TXGREEN="$(tput setaf 2 bold)" +TXYELLOW="$(tput setaf 3 bold)" +TXBLUE="$(tput setaf 4 bold)" +TXMAGENTA="$(tput setaf 5 bold)" +TXCYAN="$(tput setaf 6 bold)" +TXRESET="$(tput sgr0)" +TXCLR="$(tput el)" + +log() { + local filename="$1" lc=$2 level="$3" msg="$4" data="$5" + local txcolour flc colw + + [ "${level}" = "FAIL" ] && txcolour="${TXRED}" || txcolour="${TXYELLOW}" + [[ ${filename} =~ ^\./ ]] && filename="${filename:2}" + [ ${lc} -eq 0 ] && flc="---" || flc="$(printf "%03d" ${lc})" + [[ ${filename} =~ packages/addons/addon-depends ]] && colw=80 || colw=50 + + printf "[%s]: %3s: %-*s: %-25s: %s\n" "${txcolour}${level}${TXRESET}" "${flc}" ${colw} "${filename}" "${msg}" "${data}" +} + +process_line() { + local filename="$1" lc="$2" line="$3" inassign="$4" infunc="$5" + local var matches assignallowed=Y + + [ "${infunc}" = "Y" ] && return 0 + + rightside="${line#*=}" + + for var in PKG_SHORTDESC PKG_LONGDESC PKG_IS_ADDON PKG_NEED_UNPACK PKG_SOURCE_NAME PKG_ADDON_IS_STANDALONE \ + PKG_CONFIGURE_SCRIPT PKG_CMAKE_SCRIPT PKG_MESON_SCRIPT \ + PKG_DIR PKG_ADDON_ID PKG_BUILD \ + DESTIMAGE CC CXX CPP LD AS AR NM \ + RANLIB OBJCOPY OBJDUMP STRIP \ + CPPFLAGS CFLAGS CXXFLAGS LDFLAGS \ + PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR PKG_CONFIG_ALLOW_SYSTEM_CFLAGS PKG_CONFIG_ALLOW_SYSTEM_LIBS \ + CMAKE_CONF CMAKE \ + HOST_CC HOST_CXX HOSTCC HOSTCXX \ + CC_FOR_BUILD CXX_FOR_BUILD BUILD_CC BUILD_CXX \ + _python_sysroot _python_prefix _python_exec_prefix \ + TARGET_CONFIGURE_OPTS CMAKE_GENERATOR_NINJA TARGET_CMAKE_OPTS TARGET_MESON_OPTS \ + HOST_CONFIGURE_OPTS HOST_CMAKE_OPTS HOST_MESON_OPTS \ + INIT_CONFIGURE_OPTS INIT_CMAKE_OPTS INIT_MESON_OPTS \ + BOOTSTRAP_CONFIGURE_OPTS BOOTSTRAP_CMAKE_OPTS BOOTSTRAP_MESON_OPTS \ + ; do + + # After PKG_DIR, treat assigns to var as invalid + [ "${var}" = "PKG_DIR" ] && assignallowed=N + + if [ "${assignallowed}" = "N" ]; then + if [[ ${line} =~ (^|[[:space:]])${var}= ]]; then + [ "${inassign}" = "N" ] && matches+=", assign to ${var}" + fi + fi + + if [[ ${line} =~ \$\{${var}} ]] || [[ ${line} =~ \$${var}[^A-Za-z0-9_] ]]; then + matches+=", ref ${var}" + fi + + if [[ ${line} =~ (^|[[:space:]])unset\ ${var}($|[[:space:]]) ]]; then + matches+=", unset ${var}" + fi + done + + [ -n "${matches}" ] && log "${filename}" ${lc} "FAIL" "late binding violation" "${matches:2}" +} + +init_multi_func() { + local f t multi + + for t in target host init bootstrap; do + for f in pre_build \ + pre_configure configure post_configure \ + pre_make make post_make \ + pre_makeinstall makeinstall post_makeinstall \ + ; do + multi+=" ${f}_${t}" + done + done + echo "${multi:1}" +} + +check_func_name() { + local filename="$1" lc="$2" line="$3" + local f + + for f in configure_package \ + pre_unpack unpack post_unpack \ + pre_patch post_patch \ + ${MULTI_FUNC} \ + pre_install post_install \ + addon \ + ; do + [[ ${line} =~ ^${f} ]] && return 0 + done + + log "${filename}" ${lc} "WARN" "unknown function" "${line// *{*/}" +} + +process_pkg() { + local filename="$1" + local lc=0 isassign=N isfunc=N fc=0 intertwined=N + + while IFS= read -r line; do + lc=$((lc + 1)) + [[ ${line} =~ ^[[:space:]]*$ ]] && continue + [[ ${line} =~ ^(|[[:space:]]*)# ]] && continue + + if [[ "${line}" =~ ^[^#]*\(\)[[:space:]]*$ ]]; then + log "${filename}" ${lc} "FAIL" "bad func - missing brace" "${line}" + fi + + if [[ "${line}" =~ \(\)[[:space:]]*\{ ]]; then + isfunc=Y + fc=$((fc+1)) + check_func_name "${filename}" "${lc}" "${line}" + fi + + if [ "${intertwined}" = "N" -a "${isfunc}" = "N" -a ${fc} -ge 1 ]; then + log "${filename}" ${lc} "WARN" "intertwined vars & funcs" "${line}" + intertwined=Y + fi + + [[ "${line}" =~ ^[[:space:]]*PKG_.*=\" ]] && isassign=Y + + process_line "$1" "${lc}" "${line}" "${isassign}" "${isfunc}" + + [[ "${line}" =~ (\"$|\"[[:space:]]*$|\"[[:space:]]*#.*$) ]] && isassign=N + [[ "${line}" =~ (^}|^[[:space:]]*}) ]] && isfunc=N + done < "${filename}" + + # Duplicate function check + while read -r count line; do + [ -n "${line}" ] && log "${filename}" 0 "FAIL" "duplicate function def" "${line}" + done <<< "$(grep -E ".*() {" "${filename}" | sed 's/[[:space:]]*{.*//' | sort | uniq -c | grep -v ^[[:space:]]*1[[:space:]])" +} + +MULTI_FUNC="$(init_multi_func)" + +if [ $# -ne 0 ]; then + for arg in ${@}; do + for p in $(find packages projects -type f -path */${arg}/package.mk | sort); do + echo -en "${TXCLR}${p}...\r" >&2 + process_pkg "${p}" + done + done +else + for p in $(find packages projects -type f -name package.mk | sort); do + echo -en "${TXCLR}${p}...\r" >&2 + process_pkg "${p}" + done +fi +echo -en "${TXCLR}" >&2