blob: 94b8b65eeec3247d4b1f4d5d3239a42fadaf0748 [file] [log] [blame]
Benedek Tomasik90bd41e2021-03-10 11:23:45 +00001#-------------------------------------------------------------------------------
2# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8# Determine the number of processes to run while running parallel builds.
9# Pass -DPROCESSOR_COUNT=<n> to cmake to override.
10if(NOT DEFINED PROCESSOR_COUNT)
11 include(ProcessorCount)
12 ProcessorCount(PROCESSOR_COUNT)
13 set(PROCESSOR_COUNT ${PROCESSOR_COUNT} CACHE STRING "Number of cores to use for parallel builds.")
14endif()
15
16#[===[.rst:
17Common fetch interface for external dependencies.
18-------------------------------------------------
19#]===]
20
21#[===[.rst:
22.. cmake:command:: LazyFetch_Fetch
23
24 .. code:: cmake
25 LazyFetch_Fetch(DEP_NAME <dependency name> OPTIONS <list of options for FetchContent_Declare>)
26
27 INPUTS:
28 ``DEP_NAME``
29 Unique name for the dependency, used by FetchContent_* functions
30 ``OPTIONS``
31 List of options for FetchContent_Declare, e.g. git url and refspec, check cmake documentations for more
32 information
33 #]===]
34
35function(LazyFetch_Fetch DEP_NAME OPTIONS)
36 include(FetchContent)
37
38 # Fetching dependency
39 FetchContent_Declare(
40 ${DEP_NAME}
41 ${OPTIONS}
42 )
43
44 FetchContent_GetProperties(${DEP_NAME})
45 if(NOT "${DEP_NAME}_POPULATED")
46 message(STATUS "Fetching ${DEP_NAME}")
47 FetchContent_Populate(${DEP_NAME})
48 endif()
49endfunction()
50
51#[===[.rst:
52.. cmake:command:: LazyFetch_ConfigAndBuild
53
54 .. code:: cmake
55 LazyFetch_ConfigAndBuild(DEP_NAME <dependency name> SRC_DIR <source code dir> BIN_DIR <binary dir>
56 CACHE_FILE <path to the initial cache file> INSTALL_DIR <install path>)
57
58 INPUTS:
59 ``DEP_NAME``
60 Unique name for the dependency
61 ``SRC_DIR``
62 Source directory
63 ``BIN_DIR``
64 Build directory
65 ``CACHE_FILE``
66 Path to the initial cache file. Setting cache variables in this file can be used to augment
67 the configure process. The file goes through :cmake:function:`configure_file(... @ONLY)`, this
68 can be used to pass variables to the external project.
69 ``INSTALL_DIR``
70 Install path. If not set, the install step will be skipped.
71 #]===]
72
73function(LazyFetch_ConfigAndBuild)
74 set(oneValueArgs DEP_NAME SRC_DIR BIN_DIR CACHE_FILE INSTALL_DIR)
75 cmake_parse_arguments(BUILD "${__options}" "${oneValueArgs}" "${_multipleValueArgs}" ${ARGN})
76 message(STATUS "Configuring and building ${BUILD_DEP_NAME}")
77
78 # Store config file in build dir, so it gets cleaned up
79 set(CONFIGURED_CACHE_FILE ${CMAKE_BINARY_DIR}/${BUILD_DEP_NAME}-init-cache.cmake)
80 configure_file(${BUILD_CACHE_FILE} ${CONFIGURED_CACHE_FILE} @ONLY)
81
82 execute_process(COMMAND
83 ${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
84 ${CMAKE_COMMAND}
85 "-C${CONFIGURED_CACHE_FILE}"
86 -S ${BUILD_SRC_DIR}
87 -B ${BUILD_BIN_DIR}
88 RESULT_VARIABLE
89 _exec_error
90 )
91 if (NOT _exec_error EQUAL 0)
92 message(FATAL_ERROR "Configuring ${BUILD_DEP_NAME} build failed. `${_exec_error}`")
93 endif()
94
95 if (BUILD_INSTALL_DIR)
96 execute_process(COMMAND
97 ${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
98 ${CMAKE_COMMAND}
99 --build ${BUILD_BIN_DIR}
100 --parallel ${PROCESSOR_COUNT}
101 --target install
102 RESULT_VARIABLE
103 _exec_error
104 )
105 else()
106 execute_process(COMMAND
107 ${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
108 ${CMAKE_COMMAND}
109 --build ${BUILD_BIN_DIR}
110 --parallel ${PROCESSOR_COUNT}
111 RESULT_VARIABLE
112 _exec_error
113 )
114 endif()
115 if (NOT _exec_error EQUAL 0)
116 message(FATAL_ERROR "Building ${BUILD_DEP_NAME} failed. ${_exec_error}")
117 endif()
118endfunction()
119
120#[===[.rst:
121.. cmake:command:: LazyFetch_MakeAvailable
122
123 .. code:: cmake
124 LazyFetch_MakeAvailable(DEP_NAME <dependency name> INSTALL_DIR <install path>
125 PACKAGE_DIR <directory of moduleConfig.cmake file>
126 CACHE_FILE <path to the cache init file> FETCH_OPTIONS <options for the fetching process>)
127
128 INPUTS:
129 ``DEP_NAME``
130 If set, this path overwrites the default base path for the FetchContent process
131 ``SOURCE_DIR``
132 Location of source code.
133 ``INSTALL_DIR``
134 Build install path
135 ``PACKAGE_DIR``
136 If set find_package will search this directory for the config file
137 ``CACHE_FILE``
138 Path to the cache init file, setting cache variables in this file can be used to augment the
139 configure process. The file goes through the :cmake:function:`configure_file(... @ONLY)`, this
140 can be used to pass variables to the cache file
141 ``FETCH_OPTIONS``
142 Configure the dependency fetching process, this is passed to FetchContent_Declare, check the
143 cmake documentation for more info
144 ``SOURCE_SUBDIR``
145 A subdirectory relative to the top level directory of the fetched component, where the CMakeLists.txt file
146 can be found.
147 #]===]
148
149macro(LazyFetch_MakeAvailable)
150 set(oneValueArgs DEP_NAME SOURCE_DIR BINARY_DIR INSTALL_DIR PACKAGE_DIR CACHE_FILE SOURCE_SUBDIR)
151 set(multipleValueArgs FETCH_OPTIONS)
152 cmake_parse_arguments(MY "${__options}" "${oneValueArgs}" "${multipleValueArgs}" ${ARGN})
153 message(STATUS "Looking for dependency ${MY_DEP_NAME}")
154
155 if (NOT DEFINED MY_DEP_NAME)
156 message(FATAL_ERROR "Mandatory parameter DEP_NAME is missing.")
157 endif()
158
159 # FetchContent* functions use this form
160 string(TOLOWER ${MY_DEP_NAME} MY_LC_DEP_NAME)
161
162 # These two variables are also set by the normal FetchContent process and users could depend on them,
163 # so they are not unset at the end of the macro
164 if (MY_BINARY_DIR)
165 set(${MY_LC_DEP_NAME}_BINARY_DIR ${MY_BINARY_DIR})
166 else()
167 set(${MY_LC_DEP_NAME}_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/_deps/${MY_LC_DEP_NAME}-build CACHE PATH "Build directory for ${MY_LC_DEP_NAME}")
168 endif()
169 if (MY_SOURCE_DIR)
170 set(${MY_LC_DEP_NAME}_SOURCE_DIR ${MY_SOURCE_DIR})
171 else()
172 set(${MY_LC_DEP_NAME}_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_deps/${MY_LC_DEP_NAME}-src CACHE PATH "Source directory for ${MY_LC_DEP_NAME}")
173 endif()
174
175 set(${MY_LC_DEP_NAME}_SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/${MY_LC_DEP_NAME}-subbuild")
176
177 list(APPEND MY_FETCH_OPTIONS
178 SOURCE_DIR "${${MY_LC_DEP_NAME}_SOURCE_DIR}"
179 BINARY_DIR "${${MY_LC_DEP_NAME}_BINARY_DIR}"
180 SUBBUILD_DIR "${${MY_LC_DEP_NAME}_SUBBUILD_DIR}")
181
182 if (NOT DEFINED MY_INSTALL_DIR OR NOT EXISTS ${MY_INSTALL_DIR})
183 if (NOT EXISTS ${${MY_LC_DEP_NAME}_BINARY_DIR} OR NOT EXISTS ${${MY_LC_DEP_NAME}_SOURCE_DIR})
184 if (NOT EXISTS ${${MY_LC_DEP_NAME}_SOURCE_DIR})
185 LazyFetch_Fetch(${MY_LC_DEP_NAME} "${MY_FETCH_OPTIONS}")
186 file(REMOVE_RECURSE "${${MY_LC_DEP_NAME}_BINARY_DIR}")
187 file(REMOVE_RECURSE "${${MY_LC_DEP_NAME}_SUBBUILD_DIR}")
188 endif()
189 if (MY_CACHE_FILE)
190 LazyFetch_ConfigAndBuild(
191 DEP_NAME ${MY_LC_DEP_NAME}
192 SRC_DIR ${${MY_LC_DEP_NAME}_SOURCE_DIR}/${MY_SOURCE_SUBDIR}
193 BIN_DIR ${${MY_LC_DEP_NAME}_BINARY_DIR}
194 CACHE_FILE ${MY_CACHE_FILE}
195 INSTALL_DIR ${MY_INSTALL_DIR}
196 )
197 endif()
198 elseif(DEFINED MY_INSTALL_DIR)
199 execute_process(COMMAND
200 ${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
201 ${CMAKE_COMMAND}
202 --build ${${MY_LC_DEP_NAME}_BINARY_DIR}
203 --parallel ${PROCESSOR_COUNT}
204 --target install
205 RESULT_VARIABLE
206 _exec_error
207 )
208 if (NOT _exec_error EQUAL 0)
209 message(FATAL_ERROR "Installing ${BUILD_DEP_NAME} failed. ${_exec_error}")
210 endif()
211 endif()
212 endif()
213
214 # Run find_package again if we just needed the build and install step
215 if (MY_PACKAGE_DIR)
216 unset(${MY_LC_DEP_NAME}_DIR)
217 unset(${MY_LC_DEP_NAME}_DIR CACHE)
218 unset(${MY_DEP_NAME}-FOUND CACHE)
219 find_package(${MY_DEP_NAME} CONFIG REQUIRED NO_DEFAULT_PATH PATHS ${MY_PACKAGE_DIR})
220 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MY_DEP_NAME}_CONFIG)
221 endif()
222
223 unset(MY_DEP_NAME)
224 unset(MY_SOURCE_DIR)
225 unset(MY_BINARY_DIR)
226 unset(MY_INSTALL_DIR)
227 unset(MY_PACKAGE_DIR)
228 unset(MY_CACHE_FILE)
229 unset(MY_SOURCE_SUBDIR)
230 unset(MY_FETCH_OPTIONS)
231 unset(MY_LC_DEP_NAME)
232 unset(oneValueArgs)
233 unset(multipleValueArgs)
234endmacro()