blob: 40364aa8707f99e6c06efbbada0af1cbdb3e0e99 [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
22# CMAKE_ARGS arguments...
23# Optional cmake arguments to pass when configuring the project
24# TOOLCHAIN_TOOLS targets...
25# Targets for toolchain tools (defaults to clang;lld)
26# DEPENDS targets...
27# Targets that this project depends on
28# EXTRA_TARGETS targets...
29# Extra targets in the subproject to generate targets for
30# )
31function(llvm_ExternalProject_Add name source_dir)
32 cmake_parse_arguments(ARG "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL"
33 "SOURCE_DIR"
34 "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS" ${ARGN})
35 canonicalize_tool_name(${name} nameCanon)
36 if(NOT ARG_TOOLCHAIN_TOOLS)
37 set(ARG_TOOLCHAIN_TOOLS clang lld)
38 endif()
39 foreach(tool ${ARG_TOOLCHAIN_TOOLS})
40 if(TARGET ${tool})
41 list(APPEND TOOLCHAIN_TOOLS ${tool})
42 list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
43 endif()
44 endforeach()
45
46 if(NOT ARG_RUNTIME_LIBRARIES)
47 set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
48 endif()
49 foreach(lib ${ARG_RUNTIME_LIBRARIES})
50 if(TARGET ${lib})
51 list(APPEND RUNTIME_LIBRARIES ${lib})
52 endif()
53 endforeach()
54
55 list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
56 if(FOUND_CLANG GREATER -1)
57 set(CLANG_IN_TOOLCHAIN On)
58 endif()
59
60 if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
61 list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
62 endif()
63
Chris Bieneman788c95c2015-11-11 16:14:03 +000064 set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-stamps/)
65 set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-bins/)
66
67 add_custom_target(${name}-clear
68 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}
69 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR}
70 COMMENT "Clobbering ${name} build and stamp directories"
Chris Bienemandf04e792016-06-08 22:19:25 +000071 USES_TERMINAL
Chris Bieneman788c95c2015-11-11 16:14:03 +000072 )
73
74 # Find all variables that start with COMPILER_RT and populate a variable with
75 # them.
76 get_cmake_property(variableNames VARIABLES)
Chris Bieneman4cb7ab62015-11-23 23:34:09 +000077 foreach(variableName ${variableNames})
78 if(variableName MATCHES "^${nameCanon}")
79 string(REPLACE ";" "\;" value "${${variableName}}")
Chris Bieneman788c95c2015-11-11 16:14:03 +000080 list(APPEND PASSTHROUGH_VARIABLES
Chris Bieneman4b44a762015-12-03 19:47:04 +000081 -D${variableName}=${value})
Chris Bieneman788c95c2015-11-11 16:14:03 +000082 endif()
83 endforeach()
84
85 if(ARG_USE_TOOLCHAIN)
86 if(CLANG_IN_TOOLCHAIN)
87 set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
88 -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
89 endif()
90 list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
91 endif()
92
93 add_custom_command(
94 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
95 DEPENDS ${ARG_DEPENDS}
96 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
97 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
98 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
99 COMMENT "Clobbering bootstrap build and stamp directories"
100 )
101
102 add_custom_target(${name}-clobber
103 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
104
105 if(ARG_EXCLUDE_FROM_ALL)
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000106 set(exclude EXCLUDE_FROM_ALL 1)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000107 endif()
108
109 ExternalProject_Add(${name}
110 DEPENDS ${ARG_DEPENDS}
111 ${name}-clobber
112 PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
113 SOURCE_DIR ${source_dir}
114 STAMP_DIR ${STAMP_DIR}
115 BINARY_DIR ${BINARY_DIR}
116 ${exclude}
117 CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
118 ${compiler_args}
119 -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
120 ${ARG_CMAKE_ARGS}
121 ${PASSTHROUGH_VARIABLES}
122 INSTALL_COMMAND ""
123 STEP_TARGETS configure build
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000124 BUILD_ALWAYS 1
125 USES_TERMINAL_CONFIGURE 1
126 USES_TERMINAL_BUILD 1
127 USES_TERMINAL_INSTALL 1
Chris Bieneman788c95c2015-11-11 16:14:03 +0000128 )
129
Chris Bieneman788c95c2015-11-11 16:14:03 +0000130 if(ARG_USE_TOOLCHAIN)
131 set(force_deps DEPENDS ${TOOLCHAIN_BINS})
132 endif()
133
Chris Bieneman79c68d52016-04-08 22:46:04 +0000134 llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000135 ExternalProject_Add_Step(${name} clean
136 COMMAND ${run_clean}
137 COMMENT "Cleaning ${name}..."
138 DEPENDEES configure
139 ${force_deps}
140 WORKING_DIRECTORY ${BINARY_DIR}
Chris Bieneman2b5a5452016-06-09 22:41:36 +0000141 USES_TERMINAL 1
Chris Bieneman788c95c2015-11-11 16:14:03 +0000142 )
143 ExternalProject_Add_StepTargets(${name} clean)
144
145 if(ARG_USE_TOOLCHAIN)
146 add_dependencies(${name}-clean ${name}-clobber)
147 set_target_properties(${name}-clean PROPERTIES
148 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
149 endif()
150
151 if(NOT ARG_NO_INSTALL)
152 install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${BINARY_DIR}/cmake_install.cmake \)"
153 COMPONENT ${name})
154
155 add_custom_target(install-${name}
156 DEPENDS ${name}
157 COMMAND "${CMAKE_COMMAND}"
158 -DCMAKE_INSTALL_COMPONENT=${name}
159 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
Chris Bienemandf04e792016-06-08 22:19:25 +0000160 USES_TERMINAL)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000161 endif()
162
163 # Add top-level targets
164 foreach(target ${ARG_EXTRA_TARGETS})
Chris Bieneman79c68d52016-04-08 22:46:04 +0000165 llvm_ExternalProject_BuildCmd(build_runtime_cmd ${target} ${BINARY_DIR})
Chris Bieneman788c95c2015-11-11 16:14:03 +0000166 add_custom_target(${target}
167 COMMAND ${build_runtime_cmd}
168 DEPENDS ${name}-configure
169 WORKING_DIRECTORY ${BINARY_DIR}
170 VERBATIM
Chris Bienemandf04e792016-06-08 22:19:25 +0000171 USES_TERMINAL)
Chris Bieneman788c95c2015-11-11 16:14:03 +0000172 endforeach()
173endfunction()