blob: 8190896737f10dce84939578eb3e87f12579b2f6 [file] [log] [blame]
Chris Bieneman788c95c2015-11-11 16:14:03 +00001include(ExternalProject)
2
3# llvm_ExternalProject_BuildCmd(out_var target)
4# Utility function for constructing command lines for external project targets
Chris Bieneman79c68d52016-04-08 22:46:04 +00005function(llvm_ExternalProject_BuildCmd out_var target bin_dir)
Chris Bieneman76864f92016-09-06 20:27:07 +00006 cmake_parse_arguments(ARG "" "CONFIGURATION" "" ${ARGN})
7 if(NOT ARG_CONFIGURATION)
Shoaib Meenaiff852742019-03-30 01:35:01 +00008 set(ARG_CONFIGURATION "$<CONFIG>")
Chris Bieneman76864f92016-09-06 20:27:07 +00009 endif()
Chris Bieneman788c95c2015-11-11 16:14:03 +000010 if (CMAKE_GENERATOR MATCHES "Make")
11 # Use special command for Makefiles to support parallelism.
Chris Bieneman76864f92016-09-06 20:27:07 +000012 set(${out_var} "$(MAKE)" "-C" "${bin_dir}" "${target}" PARENT_SCOPE)
Chris Bieneman788c95c2015-11-11 16:14:03 +000013 else()
Chris Bieneman79c68d52016-04-08 22:46:04 +000014 set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
Chris Bieneman76864f92016-09-06 20:27:07 +000015 --config ${ARG_CONFIGURATION} PARENT_SCOPE)
Chris Bieneman788c95c2015-11-11 16:14:03 +000016 endif()
17endfunction()
18
19# llvm_ExternalProject_Add(name source_dir ...
20# USE_TOOLCHAIN
21# Use just-built tools (see TOOLCHAIN_TOOLS)
22# EXCLUDE_FROM_ALL
23# Exclude this project from the all target
24# NO_INSTALL
25# Don't generate install targets for this project
Chris Bieneman64adae52016-06-23 22:07:21 +000026# ALWAYS_CLEAN
27# Always clean the sub-project before building
Chris Bieneman788c95c2015-11-11 16:14:03 +000028# CMAKE_ARGS arguments...
29# Optional cmake arguments to pass when configuring the project
30# TOOLCHAIN_TOOLS targets...
31# Targets for toolchain tools (defaults to clang;lld)
32# DEPENDS targets...
33# Targets that this project depends on
34# EXTRA_TARGETS targets...
35# Extra targets in the subproject to generate targets for
Chris Bieneman64adae52016-06-23 22:07:21 +000036# PASSTHROUGH_PREFIXES prefix...
37# Extra variable prefixes (name is always included) to pass down
Petr Hosekaac819b2019-03-09 01:26:55 +000038# STRIP_TOOL path
39# Use provided strip tool instead of the default one.
Chris Bieneman788c95c2015-11-11 16:14:03 +000040# )
41function(llvm_ExternalProject_Add name source_dir)
Chris Bieneman64adae52016-06-23 22:07:21 +000042 cmake_parse_arguments(ARG
43 "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
Chris Bieneman788c95c2015-11-11 16:14:03 +000044 "SOURCE_DIR"
Petr Hosekaac819b2019-03-09 01:26:55 +000045 "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES;STRIP_TOOL"
Chris Bieneman64adae52016-06-23 22:07:21 +000046 ${ARGN})
Chris Bieneman788c95c2015-11-11 16:14:03 +000047 canonicalize_tool_name(${name} nameCanon)
48 if(NOT ARG_TOOLCHAIN_TOOLS)
49 set(ARG_TOOLCHAIN_TOOLS clang lld)
Petr Hosek024a17b2016-12-12 23:15:10 +000050 if(NOT APPLE AND NOT WIN32)
Petr Hosek0acc0242018-06-06 21:43:37 +000051 list(APPEND ARG_TOOLCHAIN_TOOLS llvm-ar llvm-ranlib llvm-nm llvm-objcopy llvm-objdump llvm-strip)
Petr Hosek024a17b2016-12-12 23:15:10 +000052 endif()
Chris Bieneman788c95c2015-11-11 16:14:03 +000053 endif()
54 foreach(tool ${ARG_TOOLCHAIN_TOOLS})
55 if(TARGET ${tool})
56 list(APPEND TOOLCHAIN_TOOLS ${tool})
57 list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
58 endif()
59 endforeach()
60
61 if(NOT ARG_RUNTIME_LIBRARIES)
62 set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
63 endif()
64 foreach(lib ${ARG_RUNTIME_LIBRARIES})
65 if(TARGET ${lib})
66 list(APPEND RUNTIME_LIBRARIES ${lib})
67 endif()
68 endforeach()
69
Chris Bieneman64adae52016-06-23 22:07:21 +000070 if(ARG_ALWAYS_CLEAN)
71 set(always_clean clean)
72 endif()
73
Chris Bieneman788c95c2015-11-11 16:14:03 +000074 list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
75 if(FOUND_CLANG GREATER -1)
76 set(CLANG_IN_TOOLCHAIN On)
77 endif()
78
79 if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
80 list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
81 endif()
82
Chris Bieneman788c95c2015-11-11 16:14:03 +000083 set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-stamps/)
84 set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-bins/)
85
86 add_custom_target(${name}-clear
87 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}
88 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR}
89 COMMENT "Clobbering ${name} build and stamp directories"
Chris Bienemandf04e792016-06-08 22:19:25 +000090 USES_TERMINAL
Chris Bieneman788c95c2015-11-11 16:14:03 +000091 )
92
Chris Bieneman64adae52016-06-23 22:07:21 +000093 # Find all variables that start with a prefix and propagate them through
Chris Bieneman788c95c2015-11-11 16:14:03 +000094 get_cmake_property(variableNames VARIABLES)
Chris Bieneman64adae52016-06-23 22:07:21 +000095
96 list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon})
97 foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
98 foreach(variableName ${variableNames})
99 if(variableName MATCHES "^${prefix}")
Petr Hosek6851c0c2017-12-05 00:15:18 +0000100 string(REPLACE ";" "|" value "${${variableName}}")
Chris Bieneman64adae52016-06-23 22:07:21 +0000101 list(APPEND PASSTHROUGH_VARIABLES
102 -D${variableName}=${value})
103 endif()
104 endforeach()
Chris Bieneman788c95c2015-11-11 16:14:03 +0000105 endforeach()
106
Saleem Abdulrasooldc1c41f2019-05-17 20:09:06 +0000107 foreach(arg ${ARG_CMAKE_ARGS})
108 if(arg MATCHES "^-DCMAKE_SYSTEM_NAME=")
109 string(REGEX REPLACE "^-DCMAKE_SYSTEM_NAME=(.*)$" "\\1" _cmake_system_name "${arg}")
110 endif()
111 endforeach()
112
Petr Hosekc046a042018-01-08 23:50:59 +0000113 if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000114 if(CLANG_IN_TOOLCHAIN)
Saleem Abdulrasooldc1c41f2019-05-17 20:09:06 +0000115 if(_cmake_system_name STREQUAL Windows)
116 set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl
117 -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl)
118 else()
119 set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
120 -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
121 endif()
Chris Bieneman788c95c2015-11-11 16:14:03 +0000122 endif()
Petr Hosek0acc0242018-06-06 21:43:37 +0000123 if(lld IN_LIST TOOLCHAIN_TOOLS)
Saleem Abdulrasooldc1c41f2019-05-17 20:09:06 +0000124 if(_cmake_system_name STREQUAL Windows)
125 list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/lld-link)
126 else()
127 list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/ld.lld)
128 endif()
Petr Hosek0acc0242018-06-06 21:43:37 +0000129 endif()
Petr Hosek024a17b2016-12-12 23:15:10 +0000130 if(llvm-ar IN_LIST TOOLCHAIN_TOOLS)
131 list(APPEND compiler_args -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
132 endif()
133 if(llvm-ranlib IN_LIST TOOLCHAIN_TOOLS)
134 list(APPEND compiler_args -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
135 endif()
Petr Hosek0acc0242018-06-06 21:43:37 +0000136 if(llvm-nm IN_LIST TOOLCHAIN_TOOLS)
137 list(APPEND compiler_args -DCMAKE_NM=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-nm)
138 endif()
139 if(llvm-objdump IN_LIST TOOLCHAIN_TOOLS)
140 list(APPEND compiler_args -DCMAKE_OBJDUMP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objdump)
141 endif()
142 if(llvm-objcopy IN_LIST TOOLCHAIN_TOOLS)
143 list(APPEND compiler_args -DCMAKE_OBJCOPY=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objcopy)
144 endif()
Petr Hosekaac819b2019-03-09 01:26:55 +0000145 if(llvm-strip IN_LIST TOOLCHAIN_TOOLS AND NOT ARG_STRIP_TOOL)
Petr Hosek0acc0242018-06-06 21:43:37 +0000146 list(APPEND compiler_args -DCMAKE_STRIP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-strip)
147 endif()
Chris Bieneman788c95c2015-11-11 16:14:03 +0000148 list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
149 endif()
150
Petr Hosekaac819b2019-03-09 01:26:55 +0000151 if(ARG_STRIP_TOOL)
152 list(APPEND compiler_args -DCMAKE_STRIP=${ARG_STRIP_TOOL})
153 endif()
154
Chris Bieneman788c95c2015-11-11 16:14:03 +0000155 add_custom_command(
156 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
157 DEPENDS ${ARG_DEPENDS}
158 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
159 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
160 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
161 COMMENT "Clobbering bootstrap build and stamp directories"
162 )
163
164 add_custom_target(${name}-clobber
165 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
166
167 if(ARG_EXCLUDE_FROM_ALL)
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000168 set(exclude EXCLUDE_FROM_ALL 1)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000169 endif()
170
Shoaib Meenai038fd002017-12-08 19:42:47 +0000171 if(CMAKE_SYSROOT)
172 set(sysroot_arg -DCMAKE_SYSROOT=${CMAKE_SYSROOT})
173 endif()
174
Petr Hosekc046a042018-01-08 23:50:59 +0000175 if(CMAKE_CROSSCOMPILING)
176 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
177 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
Petr Hosek0acc0242018-06-06 21:43:37 +0000178 -DCMAKE_LINKER=${CMAKE_LINKER}
Petr Hosekc046a042018-01-08 23:50:59 +0000179 -DCMAKE_AR=${CMAKE_AR}
Petr Hosek0acc0242018-06-06 21:43:37 +0000180 -DCMAKE_RANLIB=${CMAKE_RANLIB}
181 -DCMAKE_NM=${CMAKE_NM}
182 -DCMAKE_OBJCOPY=${CMAKE_OBJCOPY}
183 -DCMAKE_OBJDUMP=${CMAKE_OBJDUMP}
184 -DCMAKE_STRIP=${CMAKE_STRIP})
Don Hinton3c59aec2018-01-21 00:29:00 +0000185 set(llvm_config_path ${LLVM_CONFIG_PATH})
Petr Hosekf8e27b32018-11-16 04:46:48 +0000186
187 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
188 string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
189 ${PACKAGE_VERSION})
190 set(resource_dir "${LLVM_LIBRARY_DIR}/clang/${CLANG_VERSION}")
191 set(flag_types ASM C CXX MODULE_LINKER SHARED_LINKER EXE_LINKER)
192 foreach(type ${flag_types})
193 set(${type}_flag -DCMAKE_${type}_FLAGS=-resource-dir=${resource_dir})
194 endforeach()
195 string(REPLACE ";" "|" flag_string "${flag_types}")
196 foreach(arg ${ARG_CMAKE_ARGS})
197 if(arg MATCHES "^-DCMAKE_(${flag_string})_FLAGS")
198 foreach(type ${flag_types})
199 if(arg MATCHES "^-DCMAKE_${type}_FLAGS")
200 string(REGEX REPLACE "^-DCMAKE_${type}_FLAGS=(.*)$" "\\1" flag_value "${arg}")
201 set(${type}_flag "${${type}_flag} ${flag_value}")
202 endif()
203 endforeach()
204 else()
205 list(APPEND cmake_args ${arg})
206 endif()
207 endforeach()
208 foreach(type ${flag_types})
209 list(APPEND cmake_args ${${type}_flag})
210 endforeach()
211 endif()
Petr Hosekc046a042018-01-08 23:50:59 +0000212 else()
213 set(llvm_config_path "$<TARGET_FILE:llvm-config>")
Petr Hosekf8e27b32018-11-16 04:46:48 +0000214 set(cmake_args ${ARG_CMAKE_ARGS})
Petr Hosekc046a042018-01-08 23:50:59 +0000215 endif()
216
Chris Bieneman788c95c2015-11-11 16:14:03 +0000217 ExternalProject_Add(${name}
Chris Bieneman997ee2b2016-08-18 21:41:21 +0000218 DEPENDS ${ARG_DEPENDS} llvm-config
Chris Bieneman788c95c2015-11-11 16:14:03 +0000219 ${name}-clobber
220 PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
221 SOURCE_DIR ${source_dir}
222 STAMP_DIR ${STAMP_DIR}
223 BINARY_DIR ${BINARY_DIR}
224 ${exclude}
225 CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
226 ${compiler_args}
227 -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
Shoaib Meenai038fd002017-12-08 19:42:47 +0000228 ${sysroot_arg}
Chris Bieneman64adae52016-06-23 22:07:21 +0000229 -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
Petr Hosekc046a042018-01-08 23:50:59 +0000230 -DLLVM_CONFIG_PATH=${llvm_config_path}
Chris Bieneman64adae52016-06-23 22:07:21 +0000231 -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
Petr Hosek61633292017-11-27 22:50:48 +0000232 -DLLVM_HOST_TRIPLE=${LLVM_HOST_TRIPLE}
Petr Hosek34ea06b2017-12-13 23:49:51 +0000233 -DLLVM_HAVE_LINK_VERSION_SCRIPT=${LLVM_HAVE_LINK_VERSION_SCRIPT}
Chris Bieneman64adae52016-06-23 22:07:21 +0000234 -DPACKAGE_VERSION=${PACKAGE_VERSION}
235 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
236 -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
George Karpenkovabb54762017-07-20 23:46:46 +0000237 -DCMAKE_EXPORT_COMPILE_COMMANDS=1
Petr Hosekf8e27b32018-11-16 04:46:48 +0000238 ${cmake_args}
Chris Bieneman788c95c2015-11-11 16:14:03 +0000239 ${PASSTHROUGH_VARIABLES}
240 INSTALL_COMMAND ""
241 STEP_TARGETS configure build
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000242 BUILD_ALWAYS 1
243 USES_TERMINAL_CONFIGURE 1
244 USES_TERMINAL_BUILD 1
245 USES_TERMINAL_INSTALL 1
Petr Hosek6851c0c2017-12-05 00:15:18 +0000246 LIST_SEPARATOR |
Chris Bieneman788c95c2015-11-11 16:14:03 +0000247 )
248
Chris Bieneman788c95c2015-11-11 16:14:03 +0000249 if(ARG_USE_TOOLCHAIN)
250 set(force_deps DEPENDS ${TOOLCHAIN_BINS})
251 endif()
252
Chris Bieneman79c68d52016-04-08 22:46:04 +0000253 llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000254 ExternalProject_Add_Step(${name} clean
255 COMMAND ${run_clean}
256 COMMENT "Cleaning ${name}..."
257 DEPENDEES configure
258 ${force_deps}
259 WORKING_DIRECTORY ${BINARY_DIR}
Chris Bieneman64adae52016-06-23 22:07:21 +0000260 EXCLUDE_FROM_MAIN 1
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000261 USES_TERMINAL 1
Chris Bieneman788c95c2015-11-11 16:14:03 +0000262 )
263 ExternalProject_Add_StepTargets(${name} clean)
264
265 if(ARG_USE_TOOLCHAIN)
266 add_dependencies(${name}-clean ${name}-clobber)
267 set_target_properties(${name}-clean PROPERTIES
268 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
269 endif()
270
271 if(NOT ARG_NO_INSTALL)
Petr Hosek7629f982018-07-15 02:12:25 +0000272 install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_DO_STRIP=\${CMAKE_INSTALL_DO_STRIP} -P ${BINARY_DIR}/cmake_install.cmake\)"
Chris Bieneman788c95c2015-11-11 16:14:03 +0000273 COMPONENT ${name})
274
Shoaib Meenaia7ac2cb2017-11-30 21:48:26 +0000275 add_llvm_install_targets(install-${name}
276 DEPENDS ${name}
277 COMPONENT ${name})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000278 endif()
279
280 # Add top-level targets
281 foreach(target ${ARG_EXTRA_TARGETS})
Petr Hoseka1efebc2018-06-27 03:14:41 +0000282 if(DEFINED ${target})
283 set(external_target "${${target}}")
Petr Hosekab9991f2017-07-11 23:41:15 +0000284 else()
Petr Hoseka1efebc2018-06-27 03:14:41 +0000285 set(external_target "${target}")
Petr Hosekab9991f2017-07-11 23:41:15 +0000286 endif()
Petr Hoseka1efebc2018-06-27 03:14:41 +0000287 llvm_ExternalProject_BuildCmd(build_runtime_cmd ${external_target} ${BINARY_DIR})
288 add_custom_target(${target}
Chris Bieneman788c95c2015-11-11 16:14:03 +0000289 COMMAND ${build_runtime_cmd}
290 DEPENDS ${name}-configure
291 WORKING_DIRECTORY ${BINARY_DIR}
292 VERBATIM
Chris Bienemandf04e792016-06-08 22:19:25 +0000293 USES_TERMINAL)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000294 endforeach()
295endfunction()