From 17ce62cc2cb8db9678f6247a2d89e1192a009086 Mon Sep 17 00:00:00 2001 From: montellese Date: Sun, 22 Feb 2015 18:07:27 +0100 Subject: [PATCH 1/4] cmake: don't use an extra loop to setup addon building --- project/cmake/addons/CMakeLists.txt | 60 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 0afc622aeb566..694394e3f7715 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -203,41 +203,37 @@ foreach(addon ${addons}) file(RENAME "${extract_dir}" "${BUILD_DIR}/${id}") endif() - list(APPEND downloaded_addons ${id}) - + # setup building the addon + externalproject_add(${id} + SOURCE_DIR ${BUILD_DIR}/${id} + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + 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) + + # add "kodi-platform" as a dependency to every addon + add_dependencies(${id} kodi-platform) + + set(${id}_DEPENDS_DIR ${BUILD_DIR}/${id}/depends) + + if(EXISTS ${${id}_DEPENDS_DIR}) + include(${APP_ROOT}/project/cmake/scripts/common/handle-depends.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() endif() endif() endif() -endforeach() - -foreach(id ${downloaded_addons}) - externalproject_add(${id} - SOURCE_DIR ${BUILD_DIR}/${id} - 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) - - # add "kodi-platform" as a dependency to every addon - add_dependencies(${id} kodi-platform) - - set(${id}_DEPENDS_DIR ${BUILD_DIR}/${id}/depends) - - if(EXISTS ${${id}_DEPENDS_DIR}) - include(${APP_ROOT}/project/cmake/scripts/common/handle-depends.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() -endforeach() +endforeach( if(NEED_SUDO) add_custom_target(install From 49e90264bc1311535e3e2d3d4c5d19af2ea673db Mon Sep 17 00:00:00 2001 From: montellese Date: Sun, 22 Feb 2015 18:27:14 +0100 Subject: [PATCH 2/4] cmake: support file:// based paths for addon definitions --- project/cmake/addons/CMakeLists.txt | 133 +++++++++++++++++----------- project/cmake/addons/README | 9 +- 2 files changed, 89 insertions(+), 53 deletions(-) diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 694394e3f7715..6b22fa2e230c5 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -160,6 +160,7 @@ foreach(addon ${addons}) list(GET def 1 url) set(archive_name ${id}) + set(SOURCE_DIR "") # if there is a 3rd parameter in the file, we consider it a git revision if(deflength GREATER 2) @@ -169,71 +170,101 @@ foreach(addon ${addons}) # if we ever use other repositories, this might need adapting set(url ${url}/archive/${revision}.tar.gz) set(archive_name ${archive_name}-${revision}) + else() + # 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 and extract the addon - if(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}) + # download the addon if necessary + if(NOT "${archive_name}" STREQUAL "") + # download and extract the addon + if(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) + message(FATAL_ERROR "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}") + endif() 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) - message(FATAL_ERROR "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}") + # remove any previously extracted version of the addon + if(EXISTS "${BUILD_DIR}/${id}") + file(REMOVE_RECURSE "${BUILD_DIR}/${id}") endif() - endif() - # remove any previously extracted version of the addon - if(EXISTS "${BUILD_DIR}/${id}") - file(REMOVE_RECURSE "${BUILD_DIR}/${id}") - endif() + # 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() - # 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 "Error extracting ${BUILD_DIR}/download/${archive_name}.tar.gz") - else() - file(RENAME "${extract_dir}" "${BUILD_DIR}/${id}") + set(SOURCE_DIR ${BUILD_DIR}/${id}) endif() - # setup building the addon - externalproject_add(${id} - SOURCE_DIR ${BUILD_DIR}/${id} - INSTALL_DIR ${CMAKE_INSTALL_PREFIX} - 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) - - # add "kodi-platform" as a dependency to every addon - add_dependencies(${id} kodi-platform) - - set(${id}_DEPENDS_DIR ${BUILD_DIR}/${id}/depends) - - if(EXISTS ${${id}_DEPENDS_DIR}) - include(${APP_ROOT}/project/cmake/scripts/common/handle-depends.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}) + if(NOT "${SOURCE_DIR}" STREQUAL "" AND EXISTS ${SOURCE_DIR}) + # setup the buildsystem for the addon + externalproject_add(${id} + SOURCE_DIR ${SOURCE_DIR} + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + 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) + + # add "kodi-platform" as a dependency to every addon + add_dependencies(${id} kodi-platform) + + set(${id}_DEPENDS_DIR ${SOURCE_DIR}/depends) + + if(EXISTS ${${id}_DEPENDS_DIR}) + include(${APP_ROOT}/project/cmake/scripts/common/handle-depends.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() + else() + message(FATAL_ERROR "${id}: invalid or missing addon source directory at ${SOURCE_DIR}") endif() endif() endif() endif() -endforeach( +endforeach() if(NEED_SUDO) add_custom_target(install diff --git a/project/cmake/addons/README b/project/cmake/addons/README index c66e6681b20d4..2e6b46ad4424f 100644 --- a/project/cmake/addons/README +++ b/project/cmake/addons/README @@ -3,14 +3,19 @@ KODI ADDONS This directory contains the cmake-based buildsystem for addons. It looks into the "addons" sub-directory and parses all *.txt files recursively. Each addon must have its own .txt file in a separate sub-directory which must -follow the defined format: +follow one of the defined format: + + where * must be identical to the addon's ID as defined in the addon's addon.xml - * must be the URL of the git repository containing the addon. + * must be the URL of the git repository containing the addon * must be a valid git tag/branch/commit in the addon's git repository which will be used for the build. + * must be the URL to a .tar.gz tarball containing the addon + * must be a file:// based path to the directory containing the + addon Reserved filenames (for additional information on how to build an addon) are: From 09826ab84fa84d244c6747e309d07febaa5a7085 Mon Sep 17 00:00:00 2001 From: wsnipex Date: Tue, 3 Mar 2015 11:04:12 +0100 Subject: [PATCH 3/4] cmake: allow to override local addon location via ADDON_SRC_PREFIX --- project/cmake/addons/CMakeLists.txt | 17 +++++++++++++---- project/cmake/addons/README | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 6b22fa2e230c5..0dad18d675fca 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -92,6 +92,10 @@ else() separate_arguments(ADDONS_TO_BUILD) endif() +if(ADDON_SRC_PREFIX) + message(STATUS "Overriding addon source directory prefix: ${ADDON_SRC_PREFIX}") +endif() + if(NOT KODI_LIB_DIR) set(KODI_LIB_DIR "${DEPENDS_PATH}/lib/kodi") else() @@ -160,17 +164,22 @@ foreach(addon ${addons}) list(GET def 1 url) set(archive_name ${id}) - set(SOURCE_DIR "") + 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) + # 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) # 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}) - else() + elseif("${SOURCE_DIR}" STREQUAL "") # check if the URL starts with file:// string(REGEX MATCH "^file://.*$" local_url "${url}") diff --git a/project/cmake/addons/README b/project/cmake/addons/README index 2e6b46ad4424f..b901bb7a7b748 100644 --- a/project/cmake/addons/README +++ b/project/cmake/addons/README @@ -29,6 +29,9 @@ executing cmake with the -D= option) to e.g. access specific paths: * ADDONS_TO_BUILD is a quoted, space delimited list of s that you want to build (default is "all"). + * ADDON_SRC_PREFIX can be used to override the addon repository location. + It must point to the locally available parent directory of the addon(s) to build + will be appended to this path automatically * CMAKE_BUILD_TYPE specifies the type of the build. This can be either "Debug" or "Release" (default is "Release"). * CMAKE_INSTALL_PREFIX points to the directory where the built addons and their From 55ffd2e44acecdf6f407bd9009c8e1f907721560 Mon Sep 17 00:00:00 2001 From: montellese Date: Sun, 22 Feb 2015 18:51:50 +0100 Subject: [PATCH 4/4] [win32] cmake: improve generated Visual Studio solution --- project/cmake/addons/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 0dad18d675fca..83f424a7ccf86 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -73,6 +73,11 @@ set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}) +if(MSVC) + # move cmake specific targets to a CMakePredefinedTargets folder in Visual Studio + set_property(GLOBAL PROPERTY USE_FOLDERS ON) +endif() + if(PACKAGE_ZIP) # needed for project installing list(APPEND BUILD_ARGS -DPACKAGE_ZIP=1)