1 include(ExternalProject)
3 # llvm_ExternalProject_BuildCmd(out_var target)
4 # Utility function for constructing command lines for external project targets
5 function(llvm_ExternalProject_BuildCmd out_var target bin_dir)
6 cmake_parse_arguments(ARG "" "CONFIGURATION" "" ${ARGN})
7 if(NOT ARG_CONFIGURATION)
8 set(ARG_CONFIGURATION "$<CONFIGURATION>")
10 if (CMAKE_GENERATOR MATCHES "Make")
11 # Use special command for Makefiles to support parallelism.
12 set(${out_var} "$(MAKE)" "-C" "${bin_dir}" "${target}" PARENT_SCOPE)
14 set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
15 --config ${ARG_CONFIGURATION} PARENT_SCOPE)
19 # llvm_ExternalProject_Add(name source_dir ...
21 # Use just-built tools (see TOOLCHAIN_TOOLS)
23 # Exclude this project from the all target
25 # Don't generate install targets for this project
27 # Always clean the sub-project before building
28 # 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)
33 # Targets that this project depends on
34 # EXTRA_TARGETS targets...
35 # Extra targets in the subproject to generate targets for
36 # PASSTHROUGH_PREFIXES prefix...
37 # Extra variable prefixes (name is always included) to pass down
39 function(llvm_ExternalProject_Add name source_dir)
40 cmake_parse_arguments(ARG
41 "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
43 "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES"
45 canonicalize_tool_name(${name} nameCanon)
46 if(NOT ARG_TOOLCHAIN_TOOLS)
47 set(ARG_TOOLCHAIN_TOOLS clang lld)
48 if(NOT APPLE AND NOT WIN32)
49 list(APPEND ARG_TOOLCHAIN_TOOLS llvm-ar llvm-ranlib)
52 foreach(tool ${ARG_TOOLCHAIN_TOOLS})
54 list(APPEND TOOLCHAIN_TOOLS ${tool})
55 list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
59 if(NOT ARG_RUNTIME_LIBRARIES)
60 set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
62 foreach(lib ${ARG_RUNTIME_LIBRARIES})
64 list(APPEND RUNTIME_LIBRARIES ${lib})
69 set(always_clean clean)
72 list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
73 if(FOUND_CLANG GREATER -1)
74 set(CLANG_IN_TOOLCHAIN On)
77 if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
78 list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
81 set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-stamps/)
82 set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-bins/)
84 add_custom_target(${name}-clear
85 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}
86 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR}
87 COMMENT "Clobbering ${name} build and stamp directories"
91 # Find all variables that start with a prefix and propagate them through
92 get_cmake_property(variableNames VARIABLES)
94 list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon})
95 foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
96 foreach(variableName ${variableNames})
97 if(variableName MATCHES "^${prefix}")
98 string(REPLACE ";" "\;" value "${${variableName}}")
99 list(APPEND PASSTHROUGH_VARIABLES
100 -D${variableName}=${value})
105 if(ARG_USE_TOOLCHAIN)
106 if(CLANG_IN_TOOLCHAIN)
107 set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
108 -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
110 if(llvm-ar IN_LIST TOOLCHAIN_TOOLS)
111 list(APPEND compiler_args -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
113 if(llvm-ranlib IN_LIST TOOLCHAIN_TOOLS)
114 list(APPEND compiler_args -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
116 list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
120 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
121 DEPENDS ${ARG_DEPENDS}
122 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
123 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
124 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
125 COMMENT "Clobbering bootstrap build and stamp directories"
128 add_custom_target(${name}-clobber
129 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
131 if(ARG_EXCLUDE_FROM_ALL)
132 set(exclude EXCLUDE_FROM_ALL 1)
135 ExternalProject_Add(${name}
136 DEPENDS ${ARG_DEPENDS} llvm-config
138 PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
139 SOURCE_DIR ${source_dir}
140 STAMP_DIR ${STAMP_DIR}
141 BINARY_DIR ${BINARY_DIR}
143 CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
145 -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
146 -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
147 -DLLVM_CONFIG_PATH=$<TARGET_FILE:llvm-config>
148 -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
149 -DPACKAGE_VERSION=${PACKAGE_VERSION}
150 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
151 -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
152 -DCMAKE_EXPORT_COMPILE_COMMANDS=1
154 ${PASSTHROUGH_VARIABLES}
156 STEP_TARGETS configure build
158 USES_TERMINAL_CONFIGURE 1
159 USES_TERMINAL_BUILD 1
160 USES_TERMINAL_INSTALL 1
163 if(ARG_USE_TOOLCHAIN)
164 set(force_deps DEPENDS ${TOOLCHAIN_BINS})
167 llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
168 ExternalProject_Add_Step(${name} clean
170 COMMENT "Cleaning ${name}..."
173 WORKING_DIRECTORY ${BINARY_DIR}
177 ExternalProject_Add_StepTargets(${name} clean)
179 if(ARG_USE_TOOLCHAIN)
180 add_dependencies(${name}-clean ${name}-clobber)
181 set_target_properties(${name}-clean PROPERTIES
182 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
185 if(NOT ARG_NO_INSTALL)
186 install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${BINARY_DIR}/cmake_install.cmake \)"
189 add_custom_target(install-${name}
191 COMMAND "${CMAKE_COMMAND}"
192 -DCMAKE_INSTALL_COMPONENT=${name}
193 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
197 # Add top-level targets
198 foreach(target ${ARG_EXTRA_TARGETS})
199 string(REPLACE ":" ";" target_list ${target})
200 list(GET target_list 0 target)
201 list(LENGTH target_list target_list_len)
202 if(${target_list_len} GREATER 1)
203 list(GET target_list 1 target_name)
205 set(target_name "${target}")
207 llvm_ExternalProject_BuildCmd(build_runtime_cmd ${target} ${BINARY_DIR})
208 add_custom_target(${target_name}
209 COMMAND ${build_runtime_cmd}
210 DEPENDS ${name}-configure
211 WORKING_DIRECTORY ${BINARY_DIR}