[CodeGenPrepare] Handle all debug calls in dupRetToEnableTailCallOpts()
[llvm-complete.git] / cmake / modules / LLVMExternalProjectUtils.cmake
blob4d26a30f97becc8c58ce80d5b2374f10b4bbcc40
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>")
9   endif()
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)
13   else()
14     set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
15                                     --config ${ARG_CONFIGURATION} PARENT_SCOPE)
16   endif()
17 endfunction()
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
26 #   ALWAYS_CLEAN
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)
32 #   DEPENDS targets...
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
38 #   )
39 function(llvm_ExternalProject_Add name source_dir)
40   cmake_parse_arguments(ARG
41     "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
42     "SOURCE_DIR"
43     "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES"
44     ${ARGN})
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 llvm-nm llvm-objcopy llvm-objdump llvm-strip)
50     endif()
51   endif()
52   foreach(tool ${ARG_TOOLCHAIN_TOOLS})
53     if(TARGET ${tool})
54       list(APPEND TOOLCHAIN_TOOLS ${tool})
55       list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
56     endif()
57   endforeach()
59   if(NOT ARG_RUNTIME_LIBRARIES)
60     set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
61   endif()
62   foreach(lib ${ARG_RUNTIME_LIBRARIES})
63     if(TARGET ${lib})
64       list(APPEND RUNTIME_LIBRARIES ${lib})
65     endif()
66   endforeach()
68   if(ARG_ALWAYS_CLEAN)
69     set(always_clean clean)
70   endif()
72   list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
73   if(FOUND_CLANG GREATER -1)
74     set(CLANG_IN_TOOLCHAIN On)
75   endif()
77   if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
78     list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
79   endif()
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"
88     USES_TERMINAL
89     )
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})
101       endif()
102     endforeach()
103   endforeach()
105   if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING)
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++)
109     endif()
110     if(lld IN_LIST TOOLCHAIN_TOOLS)
111       list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/ld.lld)
112     endif()
113     if(llvm-ar IN_LIST TOOLCHAIN_TOOLS)
114       list(APPEND compiler_args -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
115     endif()
116     if(llvm-ranlib IN_LIST TOOLCHAIN_TOOLS)
117       list(APPEND compiler_args -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
118     endif()
119     if(llvm-nm IN_LIST TOOLCHAIN_TOOLS)
120       list(APPEND compiler_args -DCMAKE_NM=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-nm)
121     endif()
122     if(llvm-objdump IN_LIST TOOLCHAIN_TOOLS)
123       list(APPEND compiler_args -DCMAKE_OBJDUMP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objdump)
124     endif()
125     if(llvm-objcopy IN_LIST TOOLCHAIN_TOOLS)
126       list(APPEND compiler_args -DCMAKE_OBJCOPY=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objcopy)
127     endif()
128     if(llvm-strip IN_LIST TOOLCHAIN_TOOLS)
129       list(APPEND compiler_args -DCMAKE_STRIP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-strip)
130     endif()
131     list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
132   endif()
134   add_custom_command(
135     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
136     DEPENDS ${ARG_DEPENDS}
137     COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
138     COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
139     COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
140     COMMENT "Clobbering bootstrap build and stamp directories"
141     )
143   add_custom_target(${name}-clobber
144     DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
146   if(ARG_EXCLUDE_FROM_ALL)
147     set(exclude EXCLUDE_FROM_ALL 1)
148   endif()
150   if(CMAKE_SYSROOT)
151     set(sysroot_arg -DCMAKE_SYSROOT=${CMAKE_SYSROOT})
152   endif()
154   if(CMAKE_CROSSCOMPILING)
155     set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
156                       -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
157                       -DCMAKE_LINKER=${CMAKE_LINKER}
158                       -DCMAKE_AR=${CMAKE_AR}
159                       -DCMAKE_RANLIB=${CMAKE_RANLIB}
160                       -DCMAKE_NM=${CMAKE_NM}
161                       -DCMAKE_OBJCOPY=${CMAKE_OBJCOPY}
162                       -DCMAKE_OBJDUMP=${CMAKE_OBJDUMP}
163                       -DCMAKE_STRIP=${CMAKE_STRIP})
164     set(llvm_config_path ${LLVM_CONFIG_PATH})
166     if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
167       string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
168              ${PACKAGE_VERSION})
169       set(resource_dir "${LLVM_LIBRARY_DIR}/clang/${CLANG_VERSION}")
170       set(flag_types ASM C CXX MODULE_LINKER SHARED_LINKER EXE_LINKER)
171       foreach(type ${flag_types})
172         set(${type}_flag -DCMAKE_${type}_FLAGS=-resource-dir=${resource_dir})
173       endforeach()
174       string(REPLACE ";" "|" flag_string "${flag_types}")
175       foreach(arg ${ARG_CMAKE_ARGS})
176         if(arg MATCHES "^-DCMAKE_(${flag_string})_FLAGS")
177           foreach(type ${flag_types})
178             if(arg MATCHES "^-DCMAKE_${type}_FLAGS")
179               string(REGEX REPLACE "^-DCMAKE_${type}_FLAGS=(.*)$" "\\1" flag_value "${arg}")
180               set(${type}_flag "${${type}_flag} ${flag_value}")
181             endif()
182           endforeach()
183         else()
184           list(APPEND cmake_args ${arg})
185         endif()
186       endforeach()
187       foreach(type ${flag_types})
188         list(APPEND cmake_args ${${type}_flag})
189       endforeach()
190     endif()
191   else()
192     set(llvm_config_path "$<TARGET_FILE:llvm-config>")
193     set(cmake_args ${ARG_CMAKE_ARGS})
194   endif()
196   ExternalProject_Add(${name}
197     DEPENDS ${ARG_DEPENDS} llvm-config
198     ${name}-clobber
199     PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
200     SOURCE_DIR ${source_dir}
201     STAMP_DIR ${STAMP_DIR}
202     BINARY_DIR ${BINARY_DIR}
203     ${exclude}
204     CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
205                ${compiler_args}
206                -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
207                ${sysroot_arg}
208                -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
209                -DLLVM_CONFIG_PATH=${llvm_config_path}
210                -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
211                -DLLVM_HOST_TRIPLE=${LLVM_HOST_TRIPLE}
212                -DLLVM_HAVE_LINK_VERSION_SCRIPT=${LLVM_HAVE_LINK_VERSION_SCRIPT}
213                -DPACKAGE_VERSION=${PACKAGE_VERSION}
214                -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
215                -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
216                -DCMAKE_EXPORT_COMPILE_COMMANDS=1
217                ${cmake_args}
218                ${PASSTHROUGH_VARIABLES}
219     INSTALL_COMMAND ""
220     STEP_TARGETS configure build
221     BUILD_ALWAYS 1
222     USES_TERMINAL_CONFIGURE 1
223     USES_TERMINAL_BUILD 1
224     USES_TERMINAL_INSTALL 1
225     LIST_SEPARATOR |
226     )
228   if(ARG_USE_TOOLCHAIN)
229     set(force_deps DEPENDS ${TOOLCHAIN_BINS})
230   endif()
232   llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
233   ExternalProject_Add_Step(${name} clean
234     COMMAND ${run_clean}
235     COMMENT "Cleaning ${name}..."
236     DEPENDEES configure
237     ${force_deps}
238     WORKING_DIRECTORY ${BINARY_DIR}
239     EXCLUDE_FROM_MAIN 1
240     USES_TERMINAL 1
241     )
242   ExternalProject_Add_StepTargets(${name} clean)
244   if(ARG_USE_TOOLCHAIN)
245     add_dependencies(${name}-clean ${name}-clobber)
246     set_target_properties(${name}-clean PROPERTIES
247       SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
248   endif()
250   if(NOT ARG_NO_INSTALL)
251     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\)"
252       COMPONENT ${name})
254     add_llvm_install_targets(install-${name}
255                              DEPENDS ${name}
256                              COMPONENT ${name})
257   endif()
259   # Add top-level targets
260   foreach(target ${ARG_EXTRA_TARGETS})
261     if(DEFINED ${target})
262       set(external_target "${${target}}")
263     else()
264       set(external_target "${target}")
265     endif()
266     llvm_ExternalProject_BuildCmd(build_runtime_cmd ${external_target} ${BINARY_DIR})
267     add_custom_target(${target}
268       COMMAND ${build_runtime_cmd}
269       DEPENDS ${name}-configure
270       WORKING_DIRECTORY ${BINARY_DIR}
271       VERBATIM
272       USES_TERMINAL)
273   endforeach()
274 endfunction()