include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake) # handle addon depends function(add_addon_depends addon searchpath) # input: string addon string searchpath set(OUTPUT_DIR ${ADDON_DEPENDS_PATH}) # look for platform-specific dependencies file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt) # backward compatibility if(NOT cmake_input_files AND CORE_SYSTEM_NAME STREQUAL windowsstore) file(GLOB_RECURSE cmake_input_files ${searchpath}/windows/*.txt) endif() file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt) list(APPEND cmake_input_files ${cmake_input_files2}) foreach(file ${cmake_input_files}) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${file}) if(NOT (file MATCHES CMakeLists.txt OR file MATCHES install.txt OR file MATCHES noinstall.txt OR file MATCHES "flags.*[.]txt" OR file MATCHES deps.txt OR file MATCHES "[a-z]+-deps[.]txt" OR file MATCHES platforms.txt)) message(STATUS "Processing ${file}") file(STRINGS ${file} def) string(REPLACE " " ";" def ${def}) list(LENGTH def deflength) get_filename_component(dir ${file} DIRECTORY) # get the id of the dependency if(NOT "${def}" STREQUAL "") # read the id from the file list(GET def 0 id) else() # read the id from the filename get_filename_component(id ${file} NAME_WE) endif() # check if the dependency has a platforms.txt set(platform_found FALSE) check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found) if(${platform_found} AND NOT TARGET ${id}) # determine the download URL of the dependency set(url "") if(deflength GREATER 1) list(GET def 1 url) message(STATUS "${id} url: ${url}") endif() # check if there are any library specific flags that need to be passed on if(EXISTS ${dir}/flags.txt) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags.txt) file(STRINGS ${dir}/flags.txt extraflags) string(REPLACE " " ";" extraflags ${extraflags}) message(STATUS "${id} extraflags: ${extraflags}") endif() if(EXISTS ${dir}/flags-${CPU}.txt) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags-${CPU}.txt) file(STRINGS ${dir}/flags-${CPU}.txt archextraflags) string(REPLACE " " ";" archextraflags ${archextraflags}) message(STATUS "${id} ${CPU} extraflags: ${archextraflags}") list(APPEND extraflags ${archextraflags}) endif() set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DOUTPUT_DIR=${OUTPUT_DIR} -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} -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME} -DENABLE_STATIC=1 -DBUILD_SHARED_LIBS=0) # windows args if (CMAKE_SYSTEM_NAME STREQUAL WindowsStore OR CMAKE_SYSTEM_NAME STREQUAL Windows) list(APPEND BUILD_ARGS -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}) endif() # if there are no make rules override files available take care of manually passing on ARCH_DEFINES if(NOT CMAKE_USER_MAKE_RULES_OVERRIDE AND NOT CMAKE_USER_MAKE_RULES_OVERRIDE_CXX) # make sure we create strings, not lists set(TMP_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_DEFINES}") set(TMP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_DEFINES}") set(TMP_EXE_LINKER_FLAGS "-L${OUTPUT_DIR}/lib ${CMAKE_EXE_LINKER_FLAGS}") list(APPEND BUILD_ARGS -DCMAKE_C_FLAGS=${TMP_C_FLAGS} -DCMAKE_CXX_FLAGS=${TMP_CXX_FLAGS} -DCMAKE_EXE_LINKER_FLAGS=${TMP_EXE_LINKER_FLAGS}) endif() if(CMAKE_TOOLCHAIN_FILE) list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) message("toolchain specified") message(${BUILD_ARGS}) endif() if(ADDON_EXTRA_ARGS) string(REPLACE " " ";" ADDON_EXTRA_ARGS ${ADDON_EXTRA_ARGS}) list(APPEND BUILD_ARGS ${ADDON_EXTRA_ARGS}) message("Addon Extra Args: ${ADDON_EXTRA_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() set(PATCH_COMMAND) # if there's a CMakeLists.txt use it to prepare the build if(EXISTS ${dir}/CMakeLists.txt) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/CMakeLists.txt) list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dir}/CMakeLists.txt ${BUILD_DIR}/${id}/src/${id}) endif() # check if we have patches to apply file(GLOB patches ${dir}/*.patch) list(SORT patches) foreach(patch ${patches}) if(NOT PATCH_PROGRAM OR "${PATCH_PROGRAM}" STREQUAL "") if(NOT PATCH_EXECUTABLE) # find the path to the patch executable if(WIN32) # On Windows prioritize Git patch.exe find_package(Git) if(Git_FOUND) get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY) get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY) endif() find_program(PATCH_EXECUTABLE NAMES patch.exe HINTS ${GIT_DIR} PATH_SUFFIXES usr/bin) else() find_program(PATCH_EXECUTABLE NAMES patch) endif() if(NOT PATCH_EXECUTABLE) message(FATAL_ERROR "Missing patch command (we looked in ${CMAKE_PREFIX_PATH})") endif() endif() set(PATCH_PROGRAM ${PATCH_EXECUTABLE}) # On Windows "patch.exe" can only handle CR-LF line-endings. # Our patches have LF-only line endings - except when they # have been checked out as part of a dependency hosted on Git # and core.autocrlf=true. if(WIN32) file(READ ${patch} patch_content_hex HEX) # Force handle LF-only line endings if(NOT patch_content_hex MATCHES "0d0a") list(APPEND PATCH_PROGRAM --binary) endif() endif() endif() set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${patch}) list(APPEND PATCH_COMMAND COMMAND ${PATCH_PROGRAM} -p1 -i ${patch}) endforeach() # if there's an install.txt use it to properly install the built files set(INSTALL_COMMAND "") if(EXISTS ${dir}/install.txt) set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND} -DINPUTDIR=${BUILD_DIR}/${id}/src/${id}-build/ -DINPUTFILE=${dir}/install.txt -DDESTDIR=${OUTPUT_DIR} -DENABLE_STATIC=1 "${extraflags}" -P ${PROJECT_SOURCE_DIR}/install.cmake) elseif(EXISTS ${dir}/noinstall.txt) set(INSTALL_COMMAND INSTALL_COMMAND "") endif() # check if there's a platform-specific or generic deps.txt containing dependencies on other libraries if(EXISTS ${dir}/${CORE_SYSTEM_NAME}-deps.txt) file(STRINGS ${dir}/${CORE_SYSTEM_NAME}-deps.txt deps) message(STATUS "${id} depends: ${deps}") # backward compatibility elseif(CORE_SYSTEM_NAME STREQUAL windowsstore AND EXISTS ${dir}/windows-deps.txt) file(STRINGS ${dir}/windows-deps.txt deps) message(STATUS "${id} depends: ${deps}") elseif(EXISTS ${dir}/deps.txt) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/deps.txt) file(STRINGS ${dir}/deps.txt deps) message(STATUS "${id} depends: ${deps}") else() set(deps) endif() if(CROSS_AUTOCONF AND AUTOCONF_FILES) foreach(afile ${AUTOCONF_FILES}) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${afile}) list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E echo "AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}") list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${afile} ${BUILD_DIR}/${id}/src/${id}) endforeach() endif() # prepare the setup of the call to externalproject_add() set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id} CMAKE_ARGS ${extraflags} ${BUILD_ARGS} PATCH_COMMAND ${PATCH_COMMAND} ${INSTALL_COMMAND}) if(CMAKE_VERSION VERSION_GREATER 3.5.9) list(APPEND EXTERNALPROJECT_SETUP GIT_SHALLOW 1) endif() # if there's an url defined we need to pass that to externalproject_add() if(DEFINED url AND NOT "${url}" STREQUAL "") # check if there's a third parameter in the file if(deflength GREATER 2) # the third parameter is considered as a revision of a git repository list(GET def 2 revision) externalproject_add(${id} GIT_REPOSITORY ${url} GIT_TAG ${revision} ${EXTERNALPROJECT_SETUP}) # For patchfiles to work, disable (users globally set) autocrlf=true if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER 3.7) message(AUTHOR_WARNING "Make use of GIT_CONFIG") endif() if(WIN32 AND patches) externalproject_add_step(${id} gitconfig COMMAND git config core.autocrlf false COMMAND git rm -rf --cached . COMMAND git reset --hard HEAD COMMENT "Performing gitconfig step: Disabling autocrlf to enable patching for '${id}'" DEPENDERS patch WORKING_DIRECTORY ) endif() else() set(CONFIGURE_COMMAND "") if(NOT WIN32) # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig ${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags} ${BUILD_ARGS} ${BUILD_DIR}/${id}/src/${id} -DPACKAGE_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DOUTPUT_DIR=${OUTPUT_DIR} -DCMAKE_PREFIX_PATH=${OUTPUT_DIR} -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} -DCMAKE_INCLUDE_PATH=${OUTPUT_DIR}/include) endif() set(DOWNLOAD_DIR ${BUILD_DIR}/download) if(EXISTS ${dir}/${id}.sha256) file(STRINGS ${dir}/${id}.sha256 sha256sum) list(GET sha256sum 0 sha256sum) set(URL_HASH_COMMAND URL_HASH SHA256=${sha256sum}) if(TARBALL_DIR) set(DOWNLOAD_DIR ${TARBALL_DIR}) endif() else() unset(URL_HASH_COMMAND) message(AUTHOR_WARNING "${dir}/${id}.sha256 is missing") endif() externalproject_add(${id} URL ${url} "${URL_HASH_COMMAND}" DOWNLOAD_DIR ${DOWNLOAD_DIR} CONFIGURE_COMMAND ${CONFIGURE_COMMAND} ${EXTERNALPROJECT_SETUP}) endif() else() externalproject_add(${id} SOURCE_DIR ${dir} ${EXTERNALPROJECT_SETUP}) endif() if(deps) add_dependencies(${id} ${deps}) endif() endif() # if the dependency is available for the target platform add it to the list of the addon's dependencies # (even if the target already exists as it still has to be built before the addon) if(${platform_found}) list(APPEND ${addon}_DEPS ${id}) endif() endif() endforeach() # make the ${addon}_DEPS variable available to the calling script set(${addon}_DEPS "${${addon}_DEPS}" PARENT_SCOPE) endfunction()