blob: 3e7355d4d6b2ca832c3d8f7b33a70e2869e08761 [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 Bieneman788c95c2015-11-11 16:14:03 +00006 if (CMAKE_GENERATOR MATCHES "Make")
7 # Use special command for Makefiles to support parallelism.
Chris Bieneman79c68d52016-04-08 22:46:04 +00008 set(${out_var} "$(MAKE)" "-C" "${BINARY_DIR}" "${target}" PARENT_SCOPE)
Chris Bieneman788c95c2015-11-11 16:14:03 +00009 else()
Chris Bieneman79c68d52016-04-08 22:46:04 +000010 set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
Chris Bieneman788c95c2015-11-11 16:14:03 +000011 --config $<CONFIGURATION> PARENT_SCOPE)
12 endif()
13endfunction()
14
15# llvm_ExternalProject_Add(name source_dir ...
16# USE_TOOLCHAIN
17# Use just-built tools (see TOOLCHAIN_TOOLS)
18# EXCLUDE_FROM_ALL
19# Exclude this project from the all target
20# NO_INSTALL
21# Don't generate install targets for this project
Chris Bieneman64adae52016-06-23 22:07:21 +000022# ALWAYS_CLEAN
23# Always clean the sub-project before building
Chris Bieneman788c95c2015-11-11 16:14:03 +000024# CMAKE_ARGS arguments...
25# Optional cmake arguments to pass when configuring the project
26# TOOLCHAIN_TOOLS targets...
27# Targets for toolchain tools (defaults to clang;lld)
28# DEPENDS targets...
29# Targets that this project depends on
30# EXTRA_TARGETS targets...
31# Extra targets in the subproject to generate targets for
Chris Bieneman64adae52016-06-23 22:07:21 +000032# PASSTHROUGH_PREFIXES prefix...
33# Extra variable prefixes (name is always included) to pass down
Chris Bieneman788c95c2015-11-11 16:14:03 +000034# )
35function(llvm_ExternalProject_Add name source_dir)
Chris Bieneman64adae52016-06-23 22:07:21 +000036 cmake_parse_arguments(ARG
37 "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
Chris Bieneman788c95c2015-11-11 16:14:03 +000038 "SOURCE_DIR"
Chris Bieneman64adae52016-06-23 22:07:21 +000039 "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES"
40 ${ARGN})
Chris Bieneman788c95c2015-11-11 16:14:03 +000041 canonicalize_tool_name(${name} nameCanon)
42 if(NOT ARG_TOOLCHAIN_TOOLS)
43 set(ARG_TOOLCHAIN_TOOLS clang lld)
44 endif()
45 foreach(tool ${ARG_TOOLCHAIN_TOOLS})
46 if(TARGET ${tool})
47 list(APPEND TOOLCHAIN_TOOLS ${tool})
48 list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
49 endif()
50 endforeach()
51
52 if(NOT ARG_RUNTIME_LIBRARIES)
53 set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
54 endif()
55 foreach(lib ${ARG_RUNTIME_LIBRARIES})
56 if(TARGET ${lib})
57 list(APPEND RUNTIME_LIBRARIES ${lib})
58 endif()
59 endforeach()
60
Chris Bieneman64adae52016-06-23 22:07:21 +000061 if(ARG_ALWAYS_CLEAN)
62 set(always_clean clean)
63 endif()
64
Chris Bieneman788c95c2015-11-11 16:14:03 +000065 list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
66 if(FOUND_CLANG GREATER -1)
67 set(CLANG_IN_TOOLCHAIN On)
68 endif()
69
70 if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
71 list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
72 endif()
73
Chris Bieneman788c95c2015-11-11 16:14:03 +000074 set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-stamps/)
75 set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-bins/)
76
77 add_custom_target(${name}-clear
78 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}
79 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR}
80 COMMENT "Clobbering ${name} build and stamp directories"
Chris Bienemandf04e792016-06-08 22:19:25 +000081 USES_TERMINAL
Chris Bieneman788c95c2015-11-11 16:14:03 +000082 )
83
Chris Bieneman64adae52016-06-23 22:07:21 +000084 # Find all variables that start with a prefix and propagate them through
Chris Bieneman788c95c2015-11-11 16:14:03 +000085 get_cmake_property(variableNames VARIABLES)
Chris Bieneman64adae52016-06-23 22:07:21 +000086
87 list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon})
88 foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
89 foreach(variableName ${variableNames})
90 if(variableName MATCHES "^${prefix}")
91 string(REPLACE ";" "\;" value "${${variableName}}")
92 list(APPEND PASSTHROUGH_VARIABLES
93 -D${variableName}=${value})
94 endif()
95 endforeach()
Chris Bieneman788c95c2015-11-11 16:14:03 +000096 endforeach()
97
98 if(ARG_USE_TOOLCHAIN)
99 if(CLANG_IN_TOOLCHAIN)
100 set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
101 -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
102 endif()
103 list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
104 endif()
105
106 add_custom_command(
107 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
108 DEPENDS ${ARG_DEPENDS}
109 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
110 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
111 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
112 COMMENT "Clobbering bootstrap build and stamp directories"
113 )
114
115 add_custom_target(${name}-clobber
116 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
117
118 if(ARG_EXCLUDE_FROM_ALL)
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000119 set(exclude EXCLUDE_FROM_ALL 1)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000120 endif()
121
122 ExternalProject_Add(${name}
123 DEPENDS ${ARG_DEPENDS}
124 ${name}-clobber
125 PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
126 SOURCE_DIR ${source_dir}
127 STAMP_DIR ${STAMP_DIR}
128 BINARY_DIR ${BINARY_DIR}
129 ${exclude}
130 CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
131 ${compiler_args}
132 -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
Chris Bieneman64adae52016-06-23 22:07:21 +0000133 -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
134 -DLLVM_CONFIG_PATH=$<TARGET_FILE:llvm-config>
135 -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
136 -DPACKAGE_VERSION=${PACKAGE_VERSION}
137 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
138 -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
Chris Bieneman788c95c2015-11-11 16:14:03 +0000139 ${ARG_CMAKE_ARGS}
140 ${PASSTHROUGH_VARIABLES}
141 INSTALL_COMMAND ""
142 STEP_TARGETS configure build
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000143 BUILD_ALWAYS 1
144 USES_TERMINAL_CONFIGURE 1
145 USES_TERMINAL_BUILD 1
146 USES_TERMINAL_INSTALL 1
Chris Bieneman788c95c2015-11-11 16:14:03 +0000147 )
148
Chris Bieneman788c95c2015-11-11 16:14:03 +0000149 if(ARG_USE_TOOLCHAIN)
150 set(force_deps DEPENDS ${TOOLCHAIN_BINS})
151 endif()
152
Chris Bieneman79c68d52016-04-08 22:46:04 +0000153 llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000154 ExternalProject_Add_Step(${name} clean
155 COMMAND ${run_clean}
156 COMMENT "Cleaning ${name}..."
157 DEPENDEES configure
158 ${force_deps}
159 WORKING_DIRECTORY ${BINARY_DIR}
Chris Bieneman64adae52016-06-23 22:07:21 +0000160 EXCLUDE_FROM_MAIN 1
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000161 USES_TERMINAL 1
Chris Bieneman788c95c2015-11-11 16:14:03 +0000162 )
163 ExternalProject_Add_StepTargets(${name} clean)
164
165 if(ARG_USE_TOOLCHAIN)
166 add_dependencies(${name}-clean ${name}-clobber)
167 set_target_properties(${name}-clean PROPERTIES
168 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
169 endif()
170
171 if(NOT ARG_NO_INSTALL)
172 install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${BINARY_DIR}/cmake_install.cmake \)"
173 COMPONENT ${name})
174
175 add_custom_target(install-${name}
176 DEPENDS ${name}
177 COMMAND "${CMAKE_COMMAND}"
178 -DCMAKE_INSTALL_COMPONENT=${name}
179 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
Chris Bienemandf04e792016-06-08 22:19:25 +0000180 USES_TERMINAL)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000181 endif()
182
183 # Add top-level targets
184 foreach(target ${ARG_EXTRA_TARGETS})
Chris Bieneman79c68d52016-04-08 22:46:04 +0000185 llvm_ExternalProject_BuildCmd(build_runtime_cmd ${target} ${BINARY_DIR})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000186 add_custom_target(${target}
187 COMMAND ${build_runtime_cmd}
188 DEPENDS ${name}-configure
189 WORKING_DIRECTORY ${BINARY_DIR}
190 VERBATIM
Chris Bienemandf04e792016-06-08 22:19:25 +0000191 USES_TERMINAL)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000192 endforeach()
193endfunction()