diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /cmake/addons | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | cmake/addons/CMakeLists.txt | 518 | ||||
-rw-r--r-- | cmake/addons/README.md | 49 | ||||
-rw-r--r-- | cmake/addons/bootstrap/Bootstrap.cmake | 39 | ||||
-rw-r--r-- | cmake/addons/bootstrap/CMakeLists.txt | 93 | ||||
-rw-r--r-- | cmake/addons/bootstrap/README.md | 49 | ||||
-rw-r--r-- | cmake/addons/bootstrap/repositories/binary-addons.txt | 1 | ||||
-rw-r--r-- | cmake/addons/depends/CMakeLists.txt | 41 | ||||
-rw-r--r-- | cmake/addons/depends/README | 35 | ||||
-rw-r--r-- | cmake/addons/depends/windows/CMakeLists.txt | 52 | ||||
-rw-r--r-- | cmake/addons/depends/windows/Install.cmake | 24 | ||||
-rw-r--r-- | cmake/addons/depends/windows/README | 19 | ||||
-rw-r--r-- | cmake/addons/depends/windows/prebuilt/README | 21 |
12 files changed, 941 insertions, 0 deletions
diff --git a/cmake/addons/CMakeLists.txt b/cmake/addons/CMakeLists.txt new file mode 100644 index 0000000..c1313d7 --- /dev/null +++ b/cmake/addons/CMakeLists.txt @@ -0,0 +1,518 @@ +cmake_minimum_required(VERSION 3.5) +project(kodi-addons) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +option(ADDON_TARBALL_CACHING "Cache downloaded addon source tarballs?" ON) +if(ADDON_TARBALL_CACHING) + message(STATUS "Addon source tarball caching is enabled") +else() + message(STATUS "Addon source tarball caching is disabled") +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +if(NOT CORE_SYSTEM_NAME) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(CORE_SYSTEM_NAME "osx") + else() + string(TOLOWER ${CMAKE_SYSTEM_NAME} CORE_SYSTEM_NAME) + endif() +endif() + +include(ExternalProject) + +### setup all the necessary paths +if(APP_ROOT) + set(CORE_SOURCE_DIR ${APP_ROOT}) + unset(APP_ROOT) + message(WARNING "APP_ROOT is deprecated. Please use CORE_SOURCE_DIR instead.") +endif() +if(NOT CORE_SOURCE_DIR) + set(CORE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../..) +else() + file(TO_CMAKE_PATH "${CORE_SOURCE_DIR}" CORE_SOURCE_DIR) +endif() +get_filename_component(CORE_SOURCE_DIR "${CORE_SOURCE_DIR}" ABSOLUTE) + +if(NOT BUILD_DIR) + set(BUILD_DIR "${CMAKE_BINARY_DIR}/build") +else() + file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR) +endif() +get_filename_component(BUILD_DIR "${BUILD_DIR}" ABSOLUTE) + +if(NOT ADDON_DEPENDS_PATH) + set(ADDON_DEPENDS_PATH "${BUILD_DIR}/depends") +else() + file(TO_CMAKE_PATH "${ADDON_DEPENDS_PATH}" ADDON_DEPENDS_PATH) +endif() +get_filename_component(ADDON_DEPENDS_PATH "${ADDON_DEPENDS_PATH}" ABSOLUTE) + +if(NOT PLATFORM_DIR) + set(PLATFORM_DIR ${CORE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}) + file(TO_CMAKE_PATH "${PLATFORM_DIR}" PLATFORM_DIR) +endif() + +# make sure CMAKE_PREFIX_PATH is set +if(NOT CMAKE_PREFIX_PATH) + set(CMAKE_PREFIX_PATH "${ADDON_DEPENDS_PATH}") +else() + file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) + list(APPEND CMAKE_PREFIX_PATH "${ADDON_DEPENDS_PATH}") +endif() + +# check for autoconf stuff to pass on +if(AUTOCONF_FILES) + string(REPLACE " " ";" AUTOCONF_FILES ${AUTOCONF_FILES}) + set(CROSS_AUTOCONF "yes") +endif() + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/output/addons") +endif() +list(APPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}) + +if (CMAKE_SYSTEM_NAME STREQUAL WindowsStore) + set(BUILD_ARGS_ext -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} + -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}) +endif() + +include(${CORE_SOURCE_DIR}/cmake/scripts/common/CompilerSettings.cmake) + +set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} + -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> + -DPACKAGE_CONFIG_PATH=${ADDON_DEPENDS_PATH}/lib/pkgconfig + -DADDON_DEPENDS_PATH=${ADDON_DEPENDS_PATH} + -DOVERRIDE_PATHS=${OVERRIDE_PATHS} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE} + -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX} + -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME} + -DBUILD_SHARED_LIBS=1 + -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + ${BUILD_ARGS_ext}) + +if(MSVC) + # move cmake specific targets to a CMakePredefinedTargets folder in Visual Studio + set_property(GLOBAL PROPERTY USE_FOLDERS ON) +endif() + +option(PACKAGE_ZIP "Prepare built addons for packaging" OFF) +if(PACKAGE_ZIP) + # needed for project installing + list(APPEND BUILD_ARGS -DPACKAGE_ZIP=ON) + + # figure out where to store the packaged ZIP archives + if(NOT PACKAGE_DIR) + set(PACKAGE_DIR "${BUILD_DIR}/zips") + else() + file(TO_CMAKE_PATH "${PACKAGE_DIR}" PACKAGE_DIR) + endif() + list(APPEND BUILD_ARGS -DPACKAGE_DIR=${PACKAGE_DIR}) + + message(STATUS "ZIP packaging enabled (destination: ${PACKAGE_DIR})") +endif() + +if(CMAKE_TOOLCHAIN_FILE) + list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) + message(STATUS "Toolchain specified") + message(STATUS ${BUILD_ARGS}) +endif() + +# used for addons where need special folders to store there content (if +# not set the addon define it byself). +# e.g. Google Chromium addon where his git bring: +# - "unable to create file" ... "Filename too long" +# see also WARNING by Windows on: https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart +if(THIRD_PARTY_PATH) + message(STATUS "Third party lib path specified") + message(STATUS ${THIRD_PARTY_PATH}) + list(APPEND BUILD_ARGS -DTHIRD_PARTY_PATH=${THIRD_PARTY_PATH}) +endif() + +if(NOT ADDONS_TO_BUILD) + set(ADDONS_TO_BUILD "all") +else() + string(STRIP "${ADDONS_TO_BUILD}" ADDONS_TO_BUILD) + message(STATUS "Building following addons: ${ADDONS_TO_BUILD}") + string(REPLACE " " ";" ADDONS_TO_BUILD ${ADDONS_TO_BUILD}) +endif() + +if(NOT ADDONS_DEFINITION_DIR) + set(ADDONS_DEFINITION_DIR ${PROJECT_SOURCE_DIR}/addons) +else() + file(TO_CMAKE_PATH "${ADDONS_DEFINITION_DIR}" ADDONS_DEFINITION_DIR) +endif() +get_filename_component(ADDONS_DEFINITION_DIR "${ADDONS_DEFINITION_DIR}" ABSOLUTE) + +if(ADDON_SRC_PREFIX) + if(NOT IS_ABSOLUTE ${ADDON_SRC_PREFIX}) + get_filename_component(ADDON_SRC_PREFIX "${CMAKE_BINARY_DIR}/${ADDON_SRC_PREFIX}" ABSOLUTE) + endif() + message(STATUS "Overriding addon source directory prefix: ${ADDON_SRC_PREFIX}") +endif() + +if(NOT APP_LIB_DIR) + set(APP_LIB_DIR "${ADDON_DEPENDS_PATH}/lib/kodi") +else() + file(TO_CMAKE_PATH "${APP_LIB_DIR}" APP_LIB_DIR) +endif() + +set(APP_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# check for platform specific stuff +if(EXISTS ${PLATFORM_DIR}/defines.txt) + file(STRINGS ${PLATFORM_DIR}/defines.txt platformdefines) + + if(NOT ARCH_DEFINES AND platformdefines) + set(ARCH_DEFINES ${platformdefines}) + endif() +endif() + +# include check_target_platform() function +include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake) + +set(ADDON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) +if(NOT WIN32) + # check install permissions + check_install_permissions(${CMAKE_INSTALL_PREFIX} can_write) + if(NOT ${can_write} AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(NEED_SUDO TRUE) + set(ADDON_INSTALL_DIR ${CMAKE_BINARY_DIR}/.install) + list(APPEND BUILD_ARGS -DOVERRIDE_PATHS=ON) + message(STATUS "NEED_SUDO: ${NEED_SUDO} (no write permission for ${CMAKE_INSTALL_PREFIX})") + endif() +endif() + +### prepare the build environment for the binary addons +# copy the PrepareEnv.cmake script to the depends path so that we can include it +file(COPY ${CORE_SOURCE_DIR}/cmake/scripts/common/PrepareEnv.cmake DESTINATION ${APP_LIB_DIR}) + +# add the location of PrepareEnv.cmake to CMAKE_MODULE_PATH so that it is found +list(APPEND CMAKE_MODULE_PATH ${APP_LIB_DIR}) + +# include PrepareEnv.cmake which contains the logic to install the addon header bindings etc +include(PrepareEnv) + +### add the depends subdirectory for any general dependencies +message(STATUS "\n-- ---- Preparing general dependencies ----") +add_subdirectory(depends) + +# add a custom target "package-addons" which will package and install all addons +add_custom_target(package-addons) + +### get and build all the binary addons +# look for all the addons to be built +file(GLOB_RECURSE addons ${ADDONS_DEFINITION_DIR}/*.txt) + +#if there are no addons assume that bootstrapping hasn't happened yet +if(NOT addons) + message(STATUS "Bootstrapping all default repositories as no addons were found...") + set(BOOTSTRAP_BUILD_DIR "${BUILD_DIR}/bootstrap") + + # make sure that the bootstraps build addon exists + if(NOT EXISTS ${BOOTSTRAP_BUILD_DIR}) + file(MAKE_DIRECTORY ${BOOTSTRAP_BUILD_DIR}) + endif() + + string(REPLACE ";" " " ADDONS_TO_BUILD_STR "${ADDONS_TO_BUILD}") + # generate the bootstrap buildsystem + execute_process(COMMAND ${CMAKE_COMMAND} ${PROJECT_SOURCE_DIR}/bootstrap + -DCMAKE_INSTALL_PREFIX:PATH=${ADDONS_DEFINITION_DIR} + -DBUILD_DIR:PATH=${BOOTSTRAP_BUILD_DIR} + -DADDONS_TO_BUILD:STRING=${ADDONS_TO_BUILD_STR} + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + WORKING_DIRECTORY ${BOOTSTRAP_BUILD_DIR}) + + # execute the generated bootstrap buildsystem + execute_process(COMMAND ${CMAKE_COMMAND} --build ${BOOTSTRAP_BUILD_DIR} + WORKING_DIRECTORY ${BOOTSTRAP_BUILD_DIR}) + + # now look for all the addons to be built again + file(GLOB_RECURSE addons ${ADDONS_DEFINITION_DIR}/*.txt) + + if(NOT addons) + message(FATAL_ERROR "No addons available to be built") + endif() +endif() + +# Track if at least one addon has been found. Everything else is likely an +# error either in ADDONS_TO_BUILD or in the directory configuration. +set(SUPPORTED_ADDON_FOUND FALSE) + +if(NOT ADDONS_TO_BUILD) + set(ADDONS_TO_BUILD "all") +endif() + +if(NOT ADDONS_TO_BUILD STREQUAL "all") + # Exact addon match list + set(REGEX_ADDONS_TO_BUILD ${ADDONS_TO_BUILD}) + set(EXACT_MATCH_ADDON_LIST "") + set(EXCLUDE_ADDONS "") + + foreach(addon ${ADDONS_TO_BUILD}) + set(FOUND_EXCLUSION "") + string(REGEX MATCH "^[-](.*)" FOUND_EXCLUSION "${addon}") + if(NOT FOUND_EXCLUSION STREQUAL "") + list(APPEND EXCLUDE_ADDONS ${CMAKE_MATCH_1}) + list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "-${CMAKE_MATCH_1}") + else() + foreach(addonrepoitem ${addons}) + if(NOT (addonrepoitem MATCHES platforms.txt)) + # need to strip regex chars, or the filter regex will use + string(REPLACE "*" "" strippedregex ${addon}) + if(${addonrepoitem} MATCHES "^.*\/(${strippedregex}).txt") + list(APPEND EXACT_MATCH_ADDON_LIST ${addon}) + # remove exact matches from addons_to_build + list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "${addon}") + endif() + endif() + endforeach() + endif() + endforeach() + + message(STATUS "Exclusion list: ${EXCLUDE_ADDONS}") + message(STATUS "Exact Match list: ${EXACT_MATCH_ADDON_LIST}") + message(STATUS "Regex list: ${REGEX_ADDONS_TO_BUILD}") +endif() + +foreach(addon ${addons}) + if(NOT (addon MATCHES platforms.txt)) + file(STRINGS ${addon} def) + string(REPLACE " " ";" def ${def}) + list(GET def 0 id) + + if("${ADDONS_TO_BUILD}" STREQUAL "all") + set(ADDON_FOUND TRUE) + else() + set(ADDON_EXCLUDE FALSE) + set(ADDON_FOUND FALSE) + foreach(exclusion ${EXCLUDE_ADDONS}) + if(id MATCHES "${exclusion}") + set(ADDON_EXCLUDE TRUE) + message(STATUS "Addon ${id} matches exclusion rule -${exclusion}") + break() + endif() + endforeach() + + if(ADDON_EXCLUDE) + continue() + endif() + + list(FIND EXACT_MATCH_ADDON_LIST ${id} idx) + if(idx GREATER -1) + # exact match, so build + message(STATUS "Exact match ${id}, building addon") + set(ADDON_FOUND TRUE) + else() + # regex search + foreach(ADDONLISTITEM ${REGEX_ADDONS_TO_BUILD}) + if(id MATCHES "${ADDONLISTITEM}") + message(STATUS "Pattern ${ADDONLISTITEM} matches ${id}, building addon") + set(ADDON_FOUND TRUE) + break() + endif() + endforeach() + endif() + endif() + + if(ADDON_FOUND) + message(STATUS "\n-- ---- Configuring addon ${addon} ----") + set(SUPPORTED_ADDON_FOUND TRUE) + + get_filename_component(dir ${addon} DIRECTORY) + + # check if the addon has a platforms.txt + set(platform_found FALSE) + check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found) + + if(${platform_found}) + # make sure the output directory is clean + file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/${id}/") + + # get the URL and revision of the addon + list(LENGTH def deflength) + list(GET def 1 url) + + set(archive_name ${id}) + if(ADDON_SRC_PREFIX) + set(SOURCE_DIR ${ADDON_SRC_PREFIX}/${id}) + set(archive_name "") + else() + set(SOURCE_DIR "") + endif() + + # if there is a 3rd parameter in the file, we consider it a git revision + if(deflength GREATER 2 AND "${SOURCE_DIR}" STREQUAL "") + list(GET def 2 revision) + + # we need access to a git executable + find_package(Git REQUIRED) + + # resolve revision to git hash + execute_process(COMMAND ${GIT_EXECUTABLE} ls-remote ${url} ${revision} OUTPUT_VARIABLE revision_hash) + # git ls-remote only works on branches and tag names but not on revisions + if(NOT "${revision_hash}" STREQUAL "") + string(REPLACE "\t" ";" revision_list ${revision_hash}) + list(GET revision_list 0 revision_hash) + message(STATUS "${id}: git branch/tag ${revision} resolved to hash: ${revision_hash}") + set(revision ${revision_hash}) + endif() + + # Note: downloading specific revisions via http in the format below is probably github specific + # if we ever use other repositories, this might need adapting + set(url ${url}/archive/${revision}.tar.gz) + set(archive_name ${archive_name}-${revision}) + elseif("${SOURCE_DIR}" STREQUAL "") + # check if the URL starts with file:// + string(REGEX MATCH "^file://.*$" local_url "${url}") + + #if not we assume this to be a local directory + if(local_url) + # this is not an archive + set(archive_name "") + + # remove the file:// protocol from the URL + string(REPLACE "file://" "" SOURCE_DIR "${url}") + + # on win32 we may have to remove another leading / + if(WIN32) + # check if the path is a local path + string(REGEX MATCH "^/.*$" local_path "${SOURCE_DIR}") + if(local_path) + string(SUBSTRING "${SOURCE_DIR}" 1 -1 SOURCE_DIR) + endif() + endif() + endif() + endif() + + # download the addon if necessary + if(NOT "${archive_name}" STREQUAL "") + # download and extract the addon + if(NOT ADDON_TARBALL_CACHING OR NOT EXISTS ${BUILD_DIR}/download/${archive_name}.tar.gz) + # cleanup any of the previously downloaded archives of this addon + file(GLOB archives "${BUILD_DIR}/download/${id}*.tar.gz") + if(archives) + message(STATUS "Removing old archives of ${id}: ${archives}") + file(REMOVE ${archives}) + endif() + + # download the addon + file(DOWNLOAD "${url}" "${BUILD_DIR}/download/${archive_name}.tar.gz" STATUS dlstatus LOG dllog SHOW_PROGRESS) + list(GET dlstatus 0 retcode) + if(NOT ${retcode} EQUAL 0) + file(REMOVE ${BUILD_DIR}/download/${archive_name}.tar.gz) + message(STATUS "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}") + # add a dummy target for addons to get it in addons failure file + list(APPEND ALL_ADDONS_BUILDING ${id}) + add_custom_target(${id} COMMAND ${CMAKE_COMMAND} -E echo "IGNORED ${id} - download failed" COMMAND exit 1) + continue() + endif() + endif() + + # remove any previously extracted version of the addon + file(REMOVE_RECURSE "${BUILD_DIR}/${id}") + + # extract the addon from the archive + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzvf ${BUILD_DIR}/download/${archive_name}.tar.gz + WORKING_DIRECTORY ${BUILD_DIR}) + file(GLOB extract_dir "${BUILD_DIR}/${archive_name}*") + if(extract_dir STREQUAL "") + message(FATAL_ERROR "${id}: error extracting ${BUILD_DIR}/download/${archive_name}.tar.gz") + else() + file(RENAME "${extract_dir}" "${BUILD_DIR}/${id}") + endif() + + set(SOURCE_DIR ${BUILD_DIR}/${id}) + endif() + + if(NOT "${SOURCE_DIR}" STREQUAL "" AND EXISTS ${SOURCE_DIR}) + # create a list of addons we are building + list(APPEND ALL_ADDONS_BUILDING ${id}) + + # setup the buildsystem for the addon + externalproject_add(${id} + SOURCE_DIR ${SOURCE_DIR} + INSTALL_DIR ${ADDON_INSTALL_DIR} + CMAKE_ARGS ${BUILD_ARGS}) + + # add a custom step to the external project between the configure and the build step which will always + # be executed and therefore forces a re-build of all changed files + externalproject_add_step(${id} forcebuild + COMMAND ${CMAKE_COMMAND} -E echo "Force build of ${id}" + DEPENDEES configure + DEPENDERS build + ALWAYS 1) + + set(${id}_DEPENDS_DIR ${SOURCE_DIR}/depends) + + if(EXISTS ${${id}_DEPENDS_DIR}) + include(${CORE_SOURCE_DIR}/cmake/scripts/common/HandleDepends.cmake) + add_addon_depends(${id} ${${id}_DEPENDS_DIR}) + if(${id}_DEPS AND NOT "${${id}_DEPS}" STREQUAL "") + message(STATUS "${id} DEPENDENCIES: ${${id}_DEPS}") + add_dependencies(${id} ${${id}_DEPS}) + endif() + endif() + + if(CROSS_AUTOCONF AND AUTOCONF_FILES) + if(EXISTS ${SOURCE_DIR}/bootstrap/autoreconf.txt) + file(STRINGS ${SOURCE_DIR}/bootstrap/autoreconf.txt conf_dirs) + foreach(conf_dir ${conf_dirs}) + foreach(afile ${AUTOCONF_FILES}) + message(STATUS "copying ${afile} to ${SOURCE_DIR}/${conf_dir}") + file(COPY ${afile} DESTINATION ${SOURCE_DIR}/${conf_dir}) + endforeach() + endforeach() + endif() + endif() + + # create a forwarding target to the addon-package target + get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(_isMultiConfig) + set(config --config $<CONFIG>) + endif() + add_custom_target(package-${id} + COMMAND ${CMAKE_COMMAND} --build ${id}-prefix/src/${id}-build ${config} --target addon-package + DEPENDS ${id}) + add_dependencies(package-addons package-${id}) + + else() + message(FATAL_ERROR "${id}: invalid or missing addon source directory at ${SOURCE_DIR}") + endif() + else() + # add a dummy target for addons that are unsupported on this platform + add_custom_target(${id} COMMAND ${CMAKE_COMMAND} -E echo "IGNORED ${id} - not supported on ${CORE_SYSTEM_NAME}\n") + endif() + endif() + endif() +endforeach() +message(STATUS "") + +if(NEED_SUDO) + add_custom_target(sudo-install + COMMAND ${CMAKE_COMMAND} -E echo "sudo rights needed to install to ${CMAKE_INSTALL_PREFIX}\n" + COMMAND sudo ${CMAKE_COMMAND} -E copy_directory ${ADDON_INSTALL_DIR}/ ${CMAKE_INSTALL_PREFIX}/ + COMMAND sudo -k) + + foreach(_id ${ALL_ADDONS_BUILDING}) + add_dependencies(sudo-install ${_id}) + endforeach() + message(WARNING "sudo rights needed to install to ${CMAKE_INSTALL_PREFIX}") + message(STATUS "\nplease type \"make sudo-install\"\n\n") +endif() + +if(NOT SUPPORTED_ADDON_FOUND) + message(FATAL_ERROR "${ADDONS_TO_BUILD} did not match any of the supported addons. \ + A list of supported addons can be viewed by building the 'supported_addons' target. \ + Addon definitions are loaded from ADDONS_DEFINITION_DIR (${ADDONS_DEFINITION_DIR}).") +endif() + +# add custom target "supported_addons" that returns all addons that are supported on this platform +string(REPLACE ";" " " ALL_ADDONS_BUILDING "${ALL_ADDONS_BUILDING}") +add_custom_target(supported_addons COMMAND ${CMAKE_COMMAND} -E echo "ALL_ADDONS_BUILDING: ${ALL_ADDONS_BUILDING}" VERBATIM) +add_custom_target(need-sudo COMMAND ${CMAKE_COMMAND} -E echo ${NEED_SUDO} VERBATIM) diff --git a/cmake/addons/README.md b/cmake/addons/README.md new file mode 100644 index 0000000..ed1894e --- /dev/null +++ b/cmake/addons/README.md @@ -0,0 +1,49 @@ + +# Kodi add-ons CMake based buildsystem +This directory contains the cmake-based buildsystem for Kodi add-ons. It looks into the directory pointed to by the *ADDONS_DEFINITION_DIR* option (which defaults to the *addons* sub-directory) and parses all *.txt files recursively. Each add-on must have its own `<addon-id>.txt` file in a separate sub-directory that must follow one of the defined formats: + + - `<addon-id> <git-url> <git-revision>` + - `<addon-id> <tarball-url>` + - `<addon-id> <file://path>` + +where +- `<addon-id>` must be identical to the add-on's ID as defined in the add-on's addon.xml +- `<git-url>` must be the URL of the git repository containing the add-on +- `<git-revision>` must be a valid git tag/branch/commit in the add-on's git repository which will be used for the build +- `<tarball-url>` must be the URL to a .tar.gz tarball containing the add-on +- `<file://path>` must be a *file://* based path to the directory containing the add-on + +## Reserved filenames +- **platforms.txt** + +List of platforms to build an add-on for (or *all*). Negating platforms is supported using a leading exclamation mark, e.g. *!windows*. + +Available platforms are: linux, windows, osx, ios, android and freebsd. + +#### Attention +If no add-on definitions could be found, the buildsystem assumes that the bootstrapping of the add-on definition repositories hasn't been performed yet and automatically executes the add-on bootstrapping buildsystem located in the *bootstrap* sub-directory with the default settings (i.e. *all* add-ons from all pre-defined add-on definition repositories are bootstrapped into the directory pointed to by the *ADDONS_DEFINITION_DIR* option). + +## Buildsystem variables +The buildsystem uses the following addon-related variables (which can be passed into it when executing cmake with the -D`<variable-name>=<value>` format) to manipulate the build process: +- `ADDONS_TO_BUILD` has four rules for matching a provided space delimited list: + - to build all addons, just use `all` (default is *all*) + - an exact match of an `<addon-id>` that you want to build (e.g. `ADDONS_TO_BUILD="game.libretro"`) + - a regular expression `<addon-id>` is matched against (e.g. `ADDONS_TO_BUILD="pvr.*"`) to build all pvr add-ons + - a regular expression exclusion can be made using `-<addon-id regex>` (e.g. `ADDONS_TO_BUILD="pvr.* -pvr.dvb"`) to exclude pvr.dvblink and pvr.dvbviewer, but build all other pvr add-ons +- `ADDONS_DEFINITION_DIR` points to the directory containing the definitions for the addons to be built +- `ADDON_SRC_PREFIX` can be used to override the add-on repository location. It must point to the locally available parent directory of the add-on(s) to build. `<addon-id>` will be appended to this path automatically +- `CMAKE_INSTALL_PREFIX` points to the directory where the built add-ons and their additional files (addon.xml, resources, ...) will be installed to (defaults to `<ADDON_DEPENDS_PATH>`) +- `ADDON_DEPENDS_PATH` points to the directory containing the *include* and *lib* directories of the add-ons' dependencies. +- `CORE_SOURCE_DIR` points to the root directory of the project (default is the absolute representation of ../../.. starting from this directory) +- `BUILD_DIR` points to the directory where the add-ons and their dependencies will be downloaded and built +- `PACKAGE_ZIP=ON` means that the add-ons will be 'packaged' into a common folder, rather than being placed in `<CMAKE_INSTALL_PREFIX>/lib/kodi/addons` and `<CMAKE_INSTALL_PREFIX>/share/kodi/addons` +- `PACKAGE_DIR` points to the directory where the ZIP archived add-ons will be stored after they have been packaged (defaults to `<BUILD_DIR>/zips`) +- `ADDON_TARBALL_CACHING` specifies whether downloaded add-on source tarballs should be cached or not (defaults to *ON*) + +## Deprecated buildsystem variables +Buildsystem will print a warning if you use any of the below-listed variables. For now they still work but you should adapt your workflow to the new variables. +- `APP_ROOT` - Use `CORE_SOURCE_DIR` instead + +## Building +The buildsystem makes some assumptions about the environment which must be met by whoever uses it: +- Any dependencies of the add-ons must already be built and their include and library files must be present in the path pointed to by `<CMAKE_PREFIX_PATH>` (in *include* and *lib* sub-directories) diff --git a/cmake/addons/bootstrap/Bootstrap.cmake b/cmake/addons/bootstrap/Bootstrap.cmake new file mode 100644 index 0000000..5d20302 --- /dev/null +++ b/cmake/addons/bootstrap/Bootstrap.cmake @@ -0,0 +1,39 @@ +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +# make sure that the installation location has been specified +if(NOT CMAKE_INSTALL_PREFIX) + message(FATAL_ERROR "CMAKE_INSTALL_PREFIX has not been specified") +endif() + +# figure out which addons to bootstrap (defaults to all) +if(NOT ADDONS_TO_BUILD) + set(ADDONS_TO_BUILD "all") +else() + string(STRIP "${ADDONS_TO_BUILD}" ADDONS_TO_BUILD) + message(STATUS "Bootstrapping following addons: ${ADDONS_TO_BUILD}") + string(REPLACE " " ";" ADDONS_TO_BUILD ${ADDONS_TO_BUILD}) +endif() + +# find all addon definitions and go through them +file(GLOB_RECURSE ADDON_DEFINITIONS ${PROJECT_SOURCE_DIR}/*.txt) +foreach(ADDON_DEFINITION_FILE ${ADDON_DEFINITIONS}) + # ignore platforms.txt + if(NOT (ADDON_DEFINITION_FILE MATCHES platforms.txt)) + # read the addon definition file + file(STRINGS ${ADDON_DEFINITION_FILE} ADDON_DEFINITION) + string(REPLACE " " ";" ADDON_DEFINITION ${ADDON_DEFINITION}) + + # extract the addon definition's identifier + list(GET ADDON_DEFINITION 0 ADDON_ID) + + # check if the addon definition should be built + if(ADDON_ID MATCHES "^${ADDONS_TO_BUILD}" OR ADDONS_TO_BUILD STREQUAL all) + # get the path to the addon definition directory + get_filename_component(ADDON_DEFINITION_DIR ${ADDON_DEFINITION_FILE} DIRECTORY) + + # install the addon definition + message(STATUS "Bootstrapping ${ADDON_ID} addon...") + file(INSTALL ${ADDON_DEFINITION_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX}) + endif() + endif() +endforeach() diff --git a/cmake/addons/bootstrap/CMakeLists.txt b/cmake/addons/bootstrap/CMakeLists.txt new file mode 100644 index 0000000..66b7e3d --- /dev/null +++ b/cmake/addons/bootstrap/CMakeLists.txt @@ -0,0 +1,93 @@ +cmake_minimum_required(VERSION 3.1) +project(kodi-addons-bootstrap) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +# make sure CMAKE_INSTALL_PREFIX is properly set +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/../addons") +endif() +list(APPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}) + +# figure out where the build directory is located +if(NOT BUILD_DIR) + set(BUILD_DIR "${CMAKE_BINARY_DIR}/build") +else() + file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR) +endif() +get_filename_component(BUILD_DIR "${BUILD_DIR}" ABSOLUTE) + +# make sure that the repositories to build have been specified +if(NOT REPOSITORY_TO_BUILD) + set(REPOSITORY_TO_BUILD_DEFAULT ON) + set(REPOSITORY_TO_BUILD "all") + set(REPOSITORY_REVISION "") + message(STATUS "Bootstrapping all repositories") +else() + set(REPOSITORY_TO_BUILD_DEFAULT OFF) + message(STATUS "Bootstrapping following repository: ${REPOSITORY_TO_BUILD}") +endif() + +# figure out which addons to bootstrap (defaults to all) +if(NOT ADDONS_TO_BUILD) + set(ADDONS_TO_BUILD "all") + message(STATUS "Bootstrapping all addons") +else() + message(STATUS "Bootstrapping following addons: ${ADDONS_TO_BUILD}") +endif() + +include(ExternalProject) + +function(bootstrap_repo repo_id repo_url repo_revision) + message(STATUS "Bootstrapping addons from ${repo_id} (${repo_url} ${repo_revision})...") + externalproject_add(${repo_id} + GIT_REPOSITORY ${repo_url} + GIT_TAG ${repo_revision} + PREFIX ${BUILD_DIR}/${repo_id} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} + -DPROJECT_SOURCE_DIR=<SOURCE_DIR> + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -P ${PROJECT_SOURCE_DIR}/Bootstrap.cmake + ) +endfunction() + +# look for all addons repository definitions +set(REPOSITORY_TO_BUILD_FOUND OFF) +file(GLOB repos repositories/*.txt) +foreach(repo ${repos}) + file(STRINGS ${repo} repo_definition) + string(REPLACE " " ";" repo_definition ${repo_definition}) + list(GET repo_definition 0 repo_id) + + list(FIND REPOSITORY_TO_BUILD ${repo_id} idx) + if(idx GREATER -1 OR REPOSITORY_TO_BUILD STREQUAL "all") + set(REPOSITORY_TO_BUILD_FOUND ON) + + # get the URL of the repository + list(GET repo_definition 1 repo_url) + + # get the revision of the repository if not provided as an argument + if(NOT REPOSITORY_REVISION) + list(GET repo_definition 2 repo_revision) + else() + set(repo_revision "${REPOSITORY_REVISION}") + endif() + + bootstrap_repo(${repo_id} ${repo_url} ${repo_revision}) + endif() +endforeach() + +# if we have been asked to bootstrap a specific repository (not the default one) and +# it couldn't be found in the predefined repository definitions we assume that it's a +# URL to a specific repository +if(NOT REPOSITORY_TO_BUILD_DEFAULT AND NOT REPOSITORY_TO_BUILD_FOUND) + # default to the master branch if no revision has been provided + if(NOT REPOSITORY_REVISION) + set(REPOSITORY_REVISION "master") + endif() + + bootstrap_repo(binary-addons-custom ${REPOSITORY_TO_BUILD} ${REPOSITORY_REVISION}) +endif() diff --git a/cmake/addons/bootstrap/README.md b/cmake/addons/bootstrap/README.md new file mode 100644 index 0000000..52ded74 --- /dev/null +++ b/cmake/addons/bootstrap/README.md @@ -0,0 +1,49 @@ + +# KODI ADDON DEFINITIONS BOOTSTRAPPING +This directory contains the cmake-based buildsystem for addon definitions +bootstrapping which downloads the addon definitions from one or more addon +definitions repositories. These addon definitions are then used by the addon +buildsystem to figure out which addons and which versions to build. It looks +into the "repositories" sub-directory and parses all *.txt files recursively. +Each addon definitions repository must have its own <repository>.txt file which +must follow the following defined format: +``` +<repository> <git-url> <git-revision> +``` +where +* `<repository>` is the identification of the repository. +* `<git-url>` must be the URL of the git repository containing the addon + definitions +* `<git-revision>` must be a valid git tag/branch/commit in the addon + definitions repository's git repository which will be used for the build + +The buildsystem uses the following variables (which can be passed into it when +executing cmake with the `-D<variable-name>=<value>` option): +* `CMAKE_INSTALL_PREFIX` points to the directory where the downloaded addon +definitions will be installed to (defaults to `../addons`). +* `BUILD_DIR` points to the directory where the addon definitions repositories +will be downloaded to. +* `REPOSITORY_TO_BUILD` specifies a single addon definitions repository to be +downloaded and processed (defaults to `"all"`). +* `REPOSITORY_REVISION` specifies the git revision in the addon definitions +repository which will be used for the build. This option is only valid in +combination with the `REPOSITORY_TO_BUILD` option (defaults to the git +revision specified in the repository's definition file). +* `ADDONS_TO_BUILD` is a quoted, space delimited list of `<addon-id>`s that +should be bootstrapped (default is `"all"`). + +To trigger the cmake-based buildsystem the following command must be executed +with <path> being the path to this directory (absolute or relative, allowing for +in-source and out-of-source builds). +``` +cmake <path> -G <generator> +``` + +cmake supports multiple generators, see +http://www.cmake.org/cmake/help/v2.8.8/cmake.html#section_Generators for a list. + +In case of additional options the call might look like this +``` +cmake <path> [-G <generator>] \ + -DCMAKE_INSTALL_PREFIX="<path-to-install-directory>" +```
\ No newline at end of file diff --git a/cmake/addons/bootstrap/repositories/binary-addons.txt b/cmake/addons/bootstrap/repositories/binary-addons.txt new file mode 100644 index 0000000..d286ad7 --- /dev/null +++ b/cmake/addons/bootstrap/repositories/binary-addons.txt @@ -0,0 +1 @@ +binary-addons https://github.com/xbmc/repo-binary-addons.git Nexus diff --git a/cmake/addons/depends/CMakeLists.txt b/cmake/addons/depends/CMakeLists.txt new file mode 100644 index 0000000..831e0ed --- /dev/null +++ b/cmake/addons/depends/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.1) +project(kodi-addons-depends) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +if(NOT CORE_SYSTEM_NAME) + string(TOLOWER ${CMAKE_SYSTEM_NAME} CORE_SYSTEM_NAME) +endif() + +include(ExternalProject) + +if(NOT ADDON_DEPENDS_PATH) + set(ADDON_DEPENDS_PATH ${PROJECT_SOURCE_DIR}/../build/depends) +else() + file(TO_CMAKE_PATH "${ADDON_DEPENDS_PATH}" ADDON_DEPENDS_PATH) +endif() +get_filename_component(ADDON_DEPENDS_PATH "${ADDON_DEPENDS_PATH}" ABSOLUTE) +list(APPEND CMAKE_PREFIX_PATH ${ADDON_DEPENDS_PATH}) + +if(NOT BUILD_DIR) + set(BUILD_DIR "${CMAKE_BINARY_DIR}/build") +else() + file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR) +endif() +get_filename_component(BUILD_DIR "${BUILD_DIR}" ABSOLUTE) + +## use add_addon_depends to handle the cmake based dependencies +include(${CORE_SOURCE_DIR}/cmake/scripts/common/HandleDepends.cmake) +add_addon_depends(depends "${PROJECT_SOURCE_DIR}") + +## if there's a platform-specific sub-directory containing a CMakeLists.txt, add it to the build as well +if(EXISTS ${PROJECT_SOURCE_DIR}/${CORE_SYSTEM_NAME}/CMakeLists.txt) + message(STATUS "Processing ${CORE_SYSTEM_NAME}") + add_subdirectory(${CORE_SYSTEM_NAME}) +else() + message(STATUS "No platform specific file ${PROJECT_SOURCE_DIR}/${CORE_SYSTEM_NAME}/CMakeLists.txt found") +endif() diff --git a/cmake/addons/depends/README b/cmake/addons/depends/README new file mode 100644 index 0000000..76df284 --- /dev/null +++ b/cmake/addons/depends/README @@ -0,0 +1,35 @@ +KODI ADDON DEPENDENCIES +======================= +This directory contains the cmake-based buildsystem for addon dependencies. It +looks into the "common" and the "<platform>/cmake" sub-directories and parses +all *.txt files recursively. Each dependency must have its own <dependency>.txt +file (either in the main sub-directory or in a separate subdirectory of the main +subdirectory) which must follow one of the defined formats: + * an empty file means that no extra downloads are necessary + * <dependency> + * <dependency> <url> + * <dependency> <git-url> <git-revision> +where + * <dependency> must be identical to the filename + * <url> must be the URL to an archive that is downloaded and extracted. + * <git-url> must be the URL of the git repository containing the + dependency. + * <git-revision> must be a valid git tag/branch/commit in the dependency's git + repository which will be used for the build. + +Reserved filenames (for additional information on how to build a dependency) +are: + * CMakeLists.txt: build instructions for the dependency + * install.txt: instructions on how to install the dependency's built files + * noinstall.txt: no installation step required (content is ignored) + * flags.txt: additional build flags + * flags-<CPU>.txt: additional arch specific platform build flags + * deps.txt: whitespace separated list of dependencies of this dependency + +The buildsystem uses the following depends-related variables (which can be passed +into it when executing cmake with the -D<variable-name>=<value> option) to e.g. +access specific paths: + * DEPENDS_TO_BUILD is a quoted, space delimited list of <dependency>s that + you want to build (default is "all"). + * ADDON_EXTRA_ARGS is a quoted, space delimited list of arguments passed to + all <dependency>s built (eg -DADDON_EXTRA_ARGS="-Darg1=1 -Darg2=2"). diff --git a/cmake/addons/depends/windows/CMakeLists.txt b/cmake/addons/depends/windows/CMakeLists.txt new file mode 100644 index 0000000..c8739c0 --- /dev/null +++ b/cmake/addons/depends/windows/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.1) +project(kodi-addons-depends-windows) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +include(ExternalProject) + +if(NOT ADDON_DEPENDS_PATH) + message(FATAL_ERROR "ADDON_DEPENDS_PATH (${ADDON_DEPENDS_PATH}) is not a valid target directory.") +else() + file(TO_CMAKE_PATH "${ADDON_DEPENDS_PATH}" ADDON_DEPENDS_PATH) +endif() +get_filename_component(ADDON_DEPENDS_PATH "${ADDON_DEPENDS_PATH}" ABSOLUTE) +list(APPEND CMAKE_PREFIX_PATH ${ADDON_DEPENDS_PATH}) + +if(NOT DEPENDS_TO_BUILD) + set(DEPENDS_TO_BUILD "all") +endif() + +function(add_internal id url inputfile) + externalproject_add(${id} + URL ${url} + PREFIX build/${id} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} + -DINPUTDIR=${PROJECT_BINARY_DIR}/build/${id}/src/${id} + -DINPUTFILE=${inputfile} + -DDESTDIR=${ADDON_DEPENDS_PATH} + -P ${PROJECT_SOURCE_DIR}/Install.cmake + ) +endfunction() + +file(GLOB_RECURSE download_input_files prebuilt/*.txt) +foreach(file ${download_input_files}) + if(NOT file MATCHES install.txt) + file(STRINGS ${file} def) + get_filename_component(dir ${file} DIRECTORY) + string(REPLACE " " ";" def ${def}) + list(GET def 0 id) + + list(FIND DEPENDS_TO_BUILD ${id} idx) + if(idx GREATER -1 OR DEPENDS_TO_BUILD STREQUAL "all") + list(GET def 1 url) + add_internal(${id} ${url} ${dir}/install.txt) + endif() + endif() +endforeach() diff --git a/cmake/addons/depends/windows/Install.cmake b/cmake/addons/depends/windows/Install.cmake new file mode 100644 index 0000000..9a3adbb --- /dev/null +++ b/cmake/addons/depends/windows/Install.cmake @@ -0,0 +1,24 @@ +if(EXISTS "${INPUTFILE}") + # if there's an input file we use it to determine which files to copy where + file(STRINGS ${INPUTFILE} FILES) + string(REPLACE "\n" ";" FILES "${FILES}") + foreach(file ${FILES}) + string(REPLACE " " ";" file "${file}") + list(GET file 0 dir) + list(GET file 1 dest) + list(LENGTH file deflength) + if(deflength GREATER 2) + list(GET file 2 copy) + endif() + file(GLOB files ${INPUTDIR}/${dir}) + foreach(instfile ${files}) + file(COPY ${instfile} DESTINATION ${DESTDIR}/${dest}) + if(copy) + file(COPY ${instfile} DESTINATION ${DESTDIR}/${copy}) + endif() + endforeach() + endforeach() +else() + # otherwise we assume that the content of the extracted archive is already well-formed and can just be copied + file(COPY ${INPUTDIR}/${dir} DESTINATION ${DESTDIR}) +endif()
\ No newline at end of file diff --git a/cmake/addons/depends/windows/README b/cmake/addons/depends/windows/README new file mode 100644 index 0000000..67dc594 --- /dev/null +++ b/cmake/addons/depends/windows/README @@ -0,0 +1,19 @@ +KODI WIN32 ADDON DEPENDENCIES +============================= +This directory contains the cmake-based buildsystem for dependencies (currently +only prebuilt) used by one or multiple addons. The buildsystem looks into the +"prebuilt" sub-directory, downloads all the specified dependencies, extracts +them and places them into the "depends" sub-directory. + +To trigger the cmake-based buildsystem the following command must be executed +with <path> being the path to this directory (absolute or relative, allowing for +in-source and out-of-source builds). + + cmake <path> [-G <generator>] + +cmake supports multiple generators, see +http://www.cmake.org/cmake/help/v2.8.8/cmake.html#section_Generators for a list. +For win32 builds one of the "Visual Studio XX" or the "NMake Makefiles" +generators is preferred. For the "NMake Makefiles" generator to work the above +command must be called from an environment prepared for VC++ builds (see +http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx). diff --git a/cmake/addons/depends/windows/prebuilt/README b/cmake/addons/depends/windows/prebuilt/README new file mode 100644 index 0000000..a0c70d6 --- /dev/null +++ b/cmake/addons/depends/windows/prebuilt/README @@ -0,0 +1,21 @@ +KODI WIN32 PREBUILT ADDON DEPENDENCIES +====================================== +This directory contains a file or sub-directory for every prebuilt dependency +used by one of the addons being built. There are two different modes supported. +Both include a file named <library-id>.txt which must follow the defined format + <library-id> <download-url> + +If the archive, which the <download-url> points at, contains + * only the necessary files and in the proper directory structure (i.e. an + "include" and a "lib" directory) then the file must be put into this + directory and nothing else is needed. + * unnecessary files and/or does not follow the defined directory structure + (i.e. an "include" and a "lib" directory) then the file must be put into a + sub-directory named <library-id>. Furthermore an additional file called + "install.txt" must be placed in that sub-directory. install.txt contains a + line for every path/directory/file with a destination where it must be copied + to. It must follow the defined format + <source> <destination> [<copy-destination>] + where <source> must be an existing file, directory or a path containing + wildcards, <destination> and the optional <copy-destination> must be existing + directories. |