diff options
author | Alwin Esch <alwin.esch@web.de> | 2017-05-16 11:29:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-16 11:29:35 +0100 |
commit | 9e09e617d2593754ec73246c9b7d7f3c48789420 (patch) | |
tree | b112819b2a85a7eb7a7bc19a54daa9e46992b125 /cmake | |
parent | 077dbd9e3ab690435c9729ae724ff4c46be43397 (diff) | |
parent | 3b05b50329074390d7a9f197dccf509af9c1db37 (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.cmake | 123 | ||||
-rw-r--r-- | cmake/scripts/common/GenerateVersionedFiles.cmake | 28 | ||||
-rw-r--r-- | cmake/scripts/common/Macros.cmake | 59 | ||||
-rw-r--r-- | cmake/scripts/common/PrepareEnv.cmake | 2 |
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() |