1 include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake)
4 function(add_addon_depends addon searchpath)
5 # input: string addon string searchpath
7 set(OUTPUT_DIR ${ADDON_DEPENDS_PATH})
8 # look for platform-specific dependencies
9 file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt)
10 # backward compatibility
11 if(NOT cmake_input_files AND CORE_SYSTEM_NAME STREQUAL windowsstore)
12 file(GLOB_RECURSE cmake_input_files ${searchpath}/windows/*.txt)
14 file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt)
15 list(APPEND cmake_input_files ${cmake_input_files2})
17 foreach(file ${cmake_input_files})
18 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${file})
19 if(NOT (file MATCHES CMakeLists.txt OR
20 file MATCHES install.txt OR
21 file MATCHES noinstall.txt OR
22 file MATCHES "flags.*[.]txt" OR
23 file MATCHES deps.txt OR
24 file MATCHES "[a-z]+-deps[.]txt" OR
25 file MATCHES platforms.txt))
26 message(STATUS "Processing ${file}")
27 file(STRINGS ${file} def)
28 string(REPLACE " " ";" def ${def})
29 list(LENGTH def deflength)
30 get_filename_component(dir ${file} DIRECTORY)
32 # get the id of the dependency
33 if(NOT "${def}" STREQUAL "")
34 # read the id from the file
37 # read the id from the filename
38 get_filename_component(id ${file} NAME_WE)
41 # check if the dependency has a platforms.txt
42 set(platform_found FALSE)
43 check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found)
45 if(${platform_found} AND NOT TARGET ${id})
46 # determine the download URL of the dependency
48 if(deflength GREATER 1)
50 message(STATUS "${id} url: ${url}")
53 # check if there are any library specific flags that need to be passed on
54 if(EXISTS ${dir}/flags.txt)
55 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags.txt)
56 file(STRINGS ${dir}/flags.txt extraflags)
57 string(REPLACE " " ";" extraflags ${extraflags})
59 message(STATUS "${id} extraflags: ${extraflags}")
62 if(EXISTS ${dir}/flags-${CPU}.txt)
63 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags-${CPU}.txt)
64 file(STRINGS ${dir}/flags-${CPU}.txt archextraflags)
65 string(REPLACE " " ";" archextraflags ${archextraflags})
67 message(STATUS "${id} ${CPU} extraflags: ${archextraflags}")
68 list(APPEND extraflags ${archextraflags})
71 set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
72 -DOUTPUT_DIR=${OUTPUT_DIR}
73 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
74 -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE}
75 -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX}
76 -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR}
77 -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
79 -DBUILD_SHARED_LIBS=0)
81 if (CMAKE_SYSTEM_NAME STREQUAL WindowsStore OR CMAKE_SYSTEM_NAME STREQUAL Windows)
82 list(APPEND BUILD_ARGS -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
83 -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION})
85 # if there are no make rules override files available take care of manually passing on ARCH_DEFINES
86 if(NOT CMAKE_USER_MAKE_RULES_OVERRIDE AND NOT CMAKE_USER_MAKE_RULES_OVERRIDE_CXX)
87 # make sure we create strings, not lists
88 set(TMP_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_DEFINES}")
89 set(TMP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_DEFINES}")
90 set(TMP_EXE_LINKER_FLAGS "-L${OUTPUT_DIR}/lib ${CMAKE_EXE_LINKER_FLAGS}")
91 list(APPEND BUILD_ARGS -DCMAKE_C_FLAGS=${TMP_C_FLAGS}
92 -DCMAKE_CXX_FLAGS=${TMP_CXX_FLAGS}
93 -DCMAKE_EXE_LINKER_FLAGS=${TMP_EXE_LINKER_FLAGS})
96 if(CMAKE_TOOLCHAIN_FILE)
97 list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
98 message("toolchain specified")
99 message(${BUILD_ARGS})
103 string(REPLACE " " ";" ADDON_EXTRA_ARGS ${ADDON_EXTRA_ARGS})
104 list(APPEND BUILD_ARGS ${ADDON_EXTRA_ARGS})
105 message("Addon Extra Args: ${ADDON_EXTRA_ARGS}")
108 # used for addons where need special folders to store there content (if
109 # not set the addon define it byself).
110 # e.g. Google Chromium addon where his git bring:
111 # - "unable to create file" ... "Filename too long"
112 # see also WARNING by Windows on: https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart
114 message(STATUS "Third party lib path specified")
115 message(STATUS ${THIRD_PARTY_PATH})
116 list(APPEND BUILD_ARGS -DTHIRD_PARTY_PATH=${THIRD_PARTY_PATH})
121 # if there's a CMakeLists.txt use it to prepare the build
122 if(EXISTS ${dir}/CMakeLists.txt)
123 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/CMakeLists.txt)
124 list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dir}/CMakeLists.txt ${BUILD_DIR}/${id}/src/${id})
127 # check if we have patches to apply
128 file(GLOB patches ${dir}/*.patch)
130 foreach(patch ${patches})
131 if(NOT PATCH_PROGRAM OR "${PATCH_PROGRAM}" STREQUAL "")
132 if(NOT PATCH_EXECUTABLE)
133 # find the path to the patch executable
136 # On Windows prioritize Git patch.exe
139 get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY)
140 get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY)
142 find_program(PATCH_EXECUTABLE NAMES patch.exe HINTS ${GIT_DIR} PATH_SUFFIXES usr/bin)
144 find_program(PATCH_EXECUTABLE NAMES patch)
146 if(NOT PATCH_EXECUTABLE)
147 message(FATAL_ERROR "Missing patch command (we looked in ${CMAKE_PREFIX_PATH})")
151 set(PATCH_PROGRAM ${PATCH_EXECUTABLE})
153 # On Windows "patch.exe" can only handle CR-LF line-endings.
154 # Our patches have LF-only line endings - except when they
155 # have been checked out as part of a dependency hosted on Git
156 # and core.autocrlf=true.
158 file(READ ${patch} patch_content_hex HEX)
159 # Force handle LF-only line endings
160 if(NOT patch_content_hex MATCHES "0d0a")
161 list(APPEND PATCH_PROGRAM --binary)
166 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${patch})
167 list(APPEND PATCH_COMMAND COMMAND ${PATCH_PROGRAM} -p1 -i ${patch})
171 # if there's an install.txt use it to properly install the built files
172 set(INSTALL_COMMAND "")
173 if(EXISTS ${dir}/install.txt)
174 set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND}
175 -DINPUTDIR=${BUILD_DIR}/${id}/src/${id}-build/
176 -DINPUTFILE=${dir}/install.txt
177 -DDESTDIR=${OUTPUT_DIR}
180 -P ${PROJECT_SOURCE_DIR}/install.cmake)
181 elseif(EXISTS ${dir}/noinstall.txt)
182 set(INSTALL_COMMAND INSTALL_COMMAND "")
185 # check if there's a platform-specific or generic deps.txt containing dependencies on other libraries
186 if(EXISTS ${dir}/${CORE_SYSTEM_NAME}-deps.txt)
187 file(STRINGS ${dir}/${CORE_SYSTEM_NAME}-deps.txt deps)
188 message(STATUS "${id} depends: ${deps}")
189 # backward compatibility
190 elseif(CORE_SYSTEM_NAME STREQUAL windowsstore AND EXISTS ${dir}/windows-deps.txt)
191 file(STRINGS ${dir}/windows-deps.txt deps)
192 message(STATUS "${id} depends: ${deps}")
193 elseif(EXISTS ${dir}/deps.txt)
194 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/deps.txt)
195 file(STRINGS ${dir}/deps.txt deps)
196 message(STATUS "${id} depends: ${deps}")
201 if(CROSS_AUTOCONF AND AUTOCONF_FILES)
202 foreach(afile ${AUTOCONF_FILES})
203 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${afile})
204 list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E echo "AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}")
205 list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${afile} ${BUILD_DIR}/${id}/src/${id})
209 # prepare the setup of the call to externalproject_add()
210 set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id}
211 CMAKE_ARGS ${extraflags} ${BUILD_ARGS}
212 PATCH_COMMAND ${PATCH_COMMAND}
215 if(CMAKE_VERSION VERSION_GREATER 3.5.9)
216 list(APPEND EXTERNALPROJECT_SETUP GIT_SHALLOW 1)
219 # if there's an url defined we need to pass that to externalproject_add()
220 if(DEFINED url AND NOT "${url}" STREQUAL "")
221 # check if there's a third parameter in the file
222 if(deflength GREATER 2)
223 # the third parameter is considered as a revision of a git repository
224 list(GET def 2 revision)
226 externalproject_add(${id}
227 GIT_REPOSITORY ${url}
229 ${EXTERNALPROJECT_SETUP})
231 # For patchfiles to work, disable (users globally set) autocrlf=true
232 if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER 3.7)
233 message(AUTHOR_WARNING "Make use of GIT_CONFIG")
235 if(WIN32 AND patches)
236 externalproject_add_step(${id} gitconfig
237 COMMAND git config core.autocrlf false
238 COMMAND git rm -rf --cached .
239 COMMAND git reset --hard HEAD
240 COMMENT "Performing gitconfig step: Disabling autocrlf to enable patching for '${id}'"
242 WORKING_DIRECTORY <SOURCE_DIR>)
245 set(CONFIGURE_COMMAND "")
247 # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH
248 set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig
249 ${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags} ${BUILD_ARGS}
250 ${BUILD_DIR}/${id}/src/${id}
251 -DPACKAGE_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig
252 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
253 -DOUTPUT_DIR=${OUTPUT_DIR}
254 -DCMAKE_PREFIX_PATH=${OUTPUT_DIR}
255 -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR}
256 -DCMAKE_INCLUDE_PATH=${OUTPUT_DIR}/include)
259 set(DOWNLOAD_DIR ${BUILD_DIR}/download)
260 if(EXISTS ${dir}/${id}.sha256)
261 file(STRINGS ${dir}/${id}.sha256 sha256sum)
262 list(GET sha256sum 0 sha256sum)
263 set(URL_HASH_COMMAND URL_HASH SHA256=${sha256sum})
265 set(DOWNLOAD_DIR ${TARBALL_DIR})
268 unset(URL_HASH_COMMAND)
269 message(AUTHOR_WARNING "${dir}/${id}.sha256 is missing")
272 externalproject_add(${id}
274 "${URL_HASH_COMMAND}"
275 DOWNLOAD_DIR ${DOWNLOAD_DIR}
276 CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
277 ${EXTERNALPROJECT_SETUP})
280 externalproject_add(${id}
282 ${EXTERNALPROJECT_SETUP})
286 add_dependencies(${id} ${deps})
290 # if the dependency is available for the target platform add it to the list of the addon's dependencies
291 # (even if the target already exists as it still has to be built before the addon)
292 if(${platform_found})
293 list(APPEND ${addon}_DEPS ${id})
298 # make the ${addon}_DEPS variable available to the calling script
299 set(${addon}_DEPS "${${addon}_DEPS}" PARENT_SCOPE)