aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorAlwin Esch <alwin.esch@web.de>2017-05-16 11:29:35 +0100
committerGitHub <noreply@github.com>2017-05-16 11:29:35 +0100
commit9e09e617d2593754ec73246c9b7d7f3c48789420 (patch)
treeb112819b2a85a7eb7a7bc19a54daa9e46992b125 /cmake
parent077dbd9e3ab690435c9729ae724ff4c46be43397 (diff)
parent3b05b50329074390d7a9f197dccf509af9c1db37 (diff)
Merge pull request #12029 from AlwinEsch/change_addon_xml_way-2
[cmake][addons] automate addon.xml version set
Diffstat (limited to 'cmake')
-rw-r--r--cmake/scripts/common/AddonHelpers.cmake123
-rw-r--r--cmake/scripts/common/GenerateVersionedFiles.cmake28
-rw-r--r--cmake/scripts/common/Macros.cmake59
-rw-r--r--cmake/scripts/common/PrepareEnv.cmake2
4 files changed, 193 insertions, 19 deletions
diff --git a/cmake/scripts/common/AddonHelpers.cmake b/cmake/scripts/common/AddonHelpers.cmake
index e740f6fefa..16e455d84a 100644
--- a/cmake/scripts/common/AddonHelpers.cmake
+++ b/cmake/scripts/common/AddonHelpers.cmake
@@ -35,7 +35,117 @@ endmacro()
# Build, link and optionally package an add-on
macro (build_addon target prefix libs)
addon_version(${target} ${prefix})
+
+ # Below comes the generation of a list with used sources where the includes to
+ # kodi's headers becomes checked.
+ # This goes the following steps to identify them:
+ # 1. Check headers are at own depended on addon
+ # - If so, it is checked whether the whole folder is already inserted, if
+ # not, it is added.
+ # 2. If headers are not defined independently and there is more as one source
+ # file.
+ # - If yes, it is checked whether the headers with the sources together
+ # - In case no headers are inserted and more than one source file exists,
+ # the whole addon folder is searched for headers.
+ # 3. As a last step, the actual source files are checked.
if(${prefix}_SOURCES)
+ # Read used headers from addon, needed to identitfy used kodi addon interface headers
+ if(${prefix}_HEADERS)
+ # Add the used header files defined with CMakeLists.txt from addon itself
+ if(${prefix}_HEADERS MATCHES ${PROJECT_SOURCE_DIR})
+ # include path name already complete
+ list(APPEND USED_SOURCES ${${prefix}_HEADERS})
+ else()
+ # add the complete include path to begin
+ foreach(hdr_file ${${prefix}_HEADERS})
+ list(APPEND USED_SOURCES ${PROJECT_SOURCE_DIR}/${hdr_file})
+ endforeach()
+ endif()
+ else()
+ list(LENGTH ${prefix}_SOURCES _length)
+ if(${_length} GREATER 1)
+ string(REGEX MATCHALL "[.](h)" _length ${${prefix}_SOURCES}})
+ if(NOT _length)
+ file(GLOB_RECURSE USED_SOURCES ${PROJECT_SOURCE_DIR}/*.h*)
+ if(USED_SOURCES)
+ message(AUTHOR_WARNING "Header files not defined in your CMakeLists.txt. Please consider defining ${prefix}_HEADERS as list of all headers used by this addon. Falling back to recursive scan for *.h.")
+ endif()
+ endif()
+ endif()
+ endif()
+
+ # Add the used source files defined with CMakeLists.txt from addon itself
+ if(${prefix}_SOURCES MATCHES ${PROJECT_SOURCE_DIR})
+ # include path name already complete
+ list(APPEND USED_SOURCES ${${prefix}_SOURCES})
+ else()
+ # add the complete include path to begin
+ foreach(src_file ${${prefix}_SOURCES})
+ list(APPEND USED_SOURCES ${PROJECT_SOURCE_DIR}/${src_file})
+ endforeach()
+ endif()
+
+ # Set defines used in addon.xml.in and read from versions.h to set add-on
+ # version parts automatically
+ file(STRINGS ${KODI_INCLUDE_DIR}/versions.h BIN_ADDON_PARTS)
+ foreach(loop_var ${BIN_ADDON_PARTS})
+ # Only pass strings with "#define ADDON_" from versions.h
+ if(loop_var MATCHES "#define ADDON_")
+ string(REGEX REPLACE "\\\n" " " loop_var ${loop_var}) # remove header line breaks
+ string(REGEX REPLACE "#define " "" loop_var ${loop_var}) # remove the #define name from string
+ string(REGEX MATCHALL "[a-zA-Z0-9._]+" loop_var "${loop_var}") # separate the define values to a list
+
+ # Get the definition name
+ list(GET loop_var 0 include_name)
+ # Check definition are depends who is a bigger list
+ if("${include_name}" MATCHES "_DEPENDS")
+ # Use start definition name as base for other value type
+ list(GET loop_var 0 list_name)
+ string(REPLACE "_DEPENDS" "" depends_name ${list_name})
+ string(REPLACE "_DEPENDS" "_XML_ID" xml_entry_name ${list_name})
+ string(REPLACE "_DEPENDS" "_USED" used_type_name ${list_name})
+
+ # remove the first value, not needed and wrong on "for" loop
+ list(REMOVE_AT loop_var 0)
+
+ foreach(depend_header ${loop_var})
+ string(STRIP ${depend_header} depend_header)
+ foreach(src_file ${USED_SOURCES})
+ file(STRINGS ${src_file} BIN_ADDON_SRC_PARTS)
+ foreach(loop_var ${BIN_ADDON_SRC_PARTS})
+ string(FIND "${loop_var}" "#include" matchres)
+ if("${matchres}" EQUAL 0)
+ string(REPLACE " " ";" loop_var "${loop_var}")
+ list(GET loop_var 1 include_name)
+ string(REGEX REPLACE "[<>\"]" "" include_name "${include_name}")
+ if(include_name STREQUAL ${depend_header})
+ set(ADDON_DEPENDS "${ADDON_DEPENDS}\n<import addon=\"${${xml_entry_name}}\" version=\"${${depends_name}}\"/>")
+ # Inform with them the addon header about used type
+ add_definitions(-D${used_type_name})
+ message(STATUS "Added usage definition: ${used_type_name}")
+ set(FOUND_HEADER_USAGE 1)
+ endif()
+ endif()
+ endforeach()
+ if(FOUND_HEADER_USAGE EQUAL 1) # break this loop if found but not unset, needed in parts where includes muddled up on addon
+ break()
+ endif()
+ endforeach()
+ # type is found and round becomes broken for next round with other type
+ if(FOUND_HEADER_USAGE EQUAL 1)
+ unset(FOUND_HEADER_USAGE)
+ break()
+ endif()
+ endforeach()
+ else()
+ # read the definition values and make it by the on version.h defined names public
+ list(GET loop_var 1 include_variable)
+ string(REGEX REPLACE ".*\"(.*)\"" "\\1" ${include_name} ${include_variable})
+ set(${include_name} ${${include_name}})
+ endif()
+ endif()
+ endforeach()
+
add_library(${target} ${${prefix}_SOURCES})
target_link_libraries(${target} ${${libs}})
set_target_properties(${target} PROPERTIES VERSION ${${prefix}_VERSION}
@@ -72,6 +182,15 @@ macro (build_addon target prefix libs)
set(PLATFORM ${CORE_SYSTEM_NAME})
file(READ ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in addon_file)
+
+ # If sources are present must be the depends set
+ if(${prefix}_SOURCES)
+ string(FIND "${addon_file}" "\@ADDON_DEPENDS\@" matchres)
+ if("${matchres}" EQUAL -1)
+ message(FATAL_ERROR "\"\@ADDON_DEPENDS\@\" not found in addon.xml.in.")
+ endif()
+ endif()
+
string(CONFIGURE "${addon_file}" addon_file_conf @ONLY)
file(GENERATE OUTPUT ${PROJECT_SOURCE_DIR}/${target}/addon.xml CONTENT "${addon_file_conf}")
if(${APP_NAME_UC}_BUILD_DIR)
@@ -109,7 +228,7 @@ macro (build_addon target prefix libs)
set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
list(APPEND CPACK_COMPONENTS_ALL ${target}-${${prefix}_VERSION})
# Pack files together to create an archive
- install(DIRECTORY ${target} DESTINATION ./ COMPONENT ${target}-${${prefix}_VERSION} PATTERN "*.xml.in" EXCLUDE)
+ install(DIRECTORY ${target} DESTINATION ./ COMPONENT ${target}-${${prefix}_VERSION} PATTERN "xml.in" EXCLUDE)
if(WIN32)
if(NOT CPACK_PACKAGE_DIRECTORY)
# determine the temporary path
@@ -197,7 +316,7 @@ macro (build_addon target prefix libs)
if (${prefix}_CUSTOM_BINARY)
install(FILES ${LIBRARY_LOCATION} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target} RENAME ${LIBRARY_FILENAME})
endif()
- install(DIRECTORY ${target} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons PATTERN "*.xml.in" EXCLUDE)
+ install(DIRECTORY ${target} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons PATTERN "xml.in" EXCLUDE)
if(${prefix}_CUSTOM_DATA)
install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons/${target}/resources)
endif()
diff --git a/cmake/scripts/common/GenerateVersionedFiles.cmake b/cmake/scripts/common/GenerateVersionedFiles.cmake
index 6062362fd5..90b2173e6a 100644
--- a/cmake/scripts/common/GenerateVersionedFiles.cmake
+++ b/cmake/scripts/common/GenerateVersionedFiles.cmake
@@ -1,8 +1,6 @@
include(${CORE_SOURCE_DIR}/cmake/scripts/common/Macros.cmake)
core_find_versions()
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/xbmc.addon)
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/kodi.guilib)
# configure_file without dependency tracking
# configure_file would register additional file dependencies that interfere
@@ -13,6 +11,28 @@ function(generate_versioned_file _SRC _DEST)
file(WRITE ${CMAKE_BINARY_DIR}/${_DEST} "${file_content}")
endfunction()
-generate_versioned_file(addons/xbmc.addon/addon.xml.in addons/xbmc.addon/addon.xml)
-generate_versioned_file(addons/kodi.guilib/addon.xml.in addons/kodi.guilib/addon.xml)
+# add-on xml's
+file(GLOB ADDON_XML_IN_FILE ${CORE_SOURCE_DIR}/addons/*/addon.xml.in)
+foreach(loop_var ${ADDON_XML_IN_FILE})
+ # prevent 'xbmc.json'; will be obtained from 'xbmc/interfaces/json-rpc/schema/CMakeLists.txt'.
+ if(loop_var MATCHES "xbmc.json")
+ continue()
+ endif()
+
+ list(GET loop_var 0 xml_name)
+
+ string(REPLACE "/addon.xml.in" "" source_dir ${xml_name})
+ string(REPLACE ${CORE_SOURCE_DIR} ${CMAKE_BINARY_DIR} dest_dir ${source_dir})
+ file(MAKE_DIRECTORY ${dest_dir})
+
+ # copy everything except addon.xml.in to build folder
+ file(COPY "${source_dir}" DESTINATION "${CMAKE_BINARY_DIR}/addons" REGEX ".xml.in" EXCLUDE)
+
+ configure_file(${source_dir}/addon.xml.in ${dest_dir}/addon.xml @ONLY)
+
+ unset(source_dir)
+ unset(dest_dir)
+ unset(xml_name)
+endforeach()
+
generate_versioned_file(xbmc/CompileInfo.cpp.in ${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp)
diff --git a/cmake/scripts/common/Macros.cmake b/cmake/scripts/common/Macros.cmake
index 964b59ff89..2f8306f9a1 100644
--- a/cmake/scripts/common/Macros.cmake
+++ b/cmake/scripts/common/Macros.cmake
@@ -619,9 +619,7 @@ endfunction()
# APP_ADDON_API - the addon API version in the form of 16.9.702
# FILE_VERSION - file version in the form of 16,9,702,0 - Windows only
#
-# The following variables are set from versions.h:
-# guilib_version - current ADDONGUI API version
-# guilib_version_min - minimal ADDONGUI API version
+# Set various variables defined in "versions.h"
macro(core_find_versions)
# kodi-addons project also calls this macro and uses CORE_SOURCE_DIR
# to point to core base dir
@@ -648,22 +646,59 @@ macro(core_find_versions)
string(TOLOWER ${APP_VERSION_TAG} APP_VERSION_TAG_LC)
endif()
string(REPLACE "." "," FILE_VERSION ${APP_ADDON_API}.0)
- file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h guilib_version REGEX "^.*ADDON_GLOBAL_VERSION_GUI (.*)$")
- string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version ${guilib_version})
- file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h guilib_version_min REGEX "^.*ADDON_GLOBAL_VERSION_GUI_MIN (.*)$")
- string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version_min ${guilib_version_min})
+
+ # Set defines used in addon.xml.in and read from versions.h to set add-on
+ # version parts automatically
+ # This part is nearly identical to "AddonHelpers.cmake", except location of versions.h
+ file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h BIN_ADDON_PARTS)
+ foreach(loop_var ${BIN_ADDON_PARTS})
+ string(FIND "${loop_var}" "#define ADDON_" matchres)
+ if("${matchres}" EQUAL 0)
+ string(REGEX MATCHALL "[A-Z0-9._]+|[A-Z0-9._]+$" loop_var "${loop_var}")
+ list(GET loop_var 0 include_name)
+ list(GET loop_var 1 include_version)
+ string(REGEX REPLACE ".*\"(.*)\"" "\\1" ${include_name} ${include_version})
+ endif()
+ endforeach(loop_var)
+
# unset variables not used anywhere else
unset(version_list)
unset(APP_APP_NAME)
+ unset(BIN_ADDON_PARTS)
# bail if we can't parse version.txt
if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR)
message(FATAL_ERROR "Could not determine app version! Make sure that ${CORE_SOURCE_DIR}/version.txt exists")
endif()
-
- # bail if we can't parse versions.h
- if(NOT DEFINED guilib_version OR NOT DEFINED guilib_version_min)
- message(FATAL_ERROR "Could not determine add-on API version! Make sure that ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h exists")
- endif()
endmacro()
+# add-on xml's
+# find all folders containing addon.xml.in and used to define
+# ADDON_XML_OUTPUTS, ADDON_XML_DEPENDS and ADDON_INSTALL_DATA
+function(find_addon_xml_in_files)
+ file(GLOB ADDON_XML_IN_FILE ${CMAKE_SOURCE_DIR}/addons/*/addon.xml.in)
+ foreach(loop_var ${ADDON_XML_IN_FILE})
+ list(GET loop_var 0 xml_name)
+
+ string(REPLACE "/addon.xml.in" "" xml_name ${xml_name})
+ string(REPLACE "${CORE_SOURCE_DIR}/" "" xml_name ${xml_name})
+
+ list(APPEND ADDON_XML_DEPENDS "${CORE_SOURCE_DIR}/${xml_name}/addon.xml.in")
+ list(APPEND ADDON_XML_OUTPUTS "${CMAKE_BINARY_DIR}/${xml_name}/addon.xml")
+
+ # Read content of add-on folder to have on install
+ file(GLOB ADDON_FILES "${CORE_SOURCE_DIR}/${xml_name}/*")
+ foreach(loop_var ${ADDON_FILES})
+ if(loop_var MATCHES "addon.xml.in")
+ string(REPLACE "addon.xml.in" "addon.xml" loop_var ${loop_var})
+ endif()
+
+ list(GET loop_var 0 file_name)
+ string(REPLACE "${CORE_SOURCE_DIR}/" "" file_name ${file_name})
+ list(APPEND ADDON_INSTALL_DATA "${file_name}")
+
+ unset(file_name)
+ endforeach()
+ unset(xml_name)
+ endforeach()
+endfunction()
diff --git a/cmake/scripts/common/PrepareEnv.cmake b/cmake/scripts/common/PrepareEnv.cmake
index aa6c30b5a8..4278d456b1 100644
--- a/cmake/scripts/common/PrepareEnv.cmake
+++ b/cmake/scripts/common/PrepareEnv.cmake
@@ -1,4 +1,4 @@
-# parse version.txt and libKODI_guilib.h to get the version and API info
+# parse version.txt and versions.h to get the version and API info
include(${CORE_SOURCE_DIR}/cmake/scripts/common/Macros.cmake)
core_find_versions()