[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / cmake / modules / LLVMExternalProjectUtils.cmake
blob4b5b600307ec93bf8d93b79289438d2be16842aa
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 "$<CONFIG>")
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(tool_args "${LLVM_EXTERNAL_PROJECT_BUILD_TOOL_ARGS}")
15     if(NOT tool_args STREQUAL "")
16       string(CONFIGURE "${tool_args}" tool_args @ONLY)
17       string(PREPEND tool_args "-- ")
18       separate_arguments(tool_args UNIX_COMMAND "${tool_args}")
19     endif()
20     set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
21                                     --config ${ARG_CONFIGURATION} ${tool_args} PARENT_SCOPE)
22   endif()
23 endfunction()
25 # is_msvc_triple(out_var triple)
26 #   Checks whether the passed triple refers to an MSVC environment
27 function(is_msvc_triple out_var triple)
28   if (triple MATCHES ".*-windows-msvc.*")
29     set(${out_var} TRUE PARENT_SCOPE)
30   else()
31     set(${out_var} FALSE PARENT_SCOPE)
32   endif()
33 endfunction()
36 # llvm_ExternalProject_Add(name source_dir ...
37 #   USE_TOOLCHAIN
38 #     Use just-built tools (see TOOLCHAIN_TOOLS)
39 #   EXCLUDE_FROM_ALL
40 #     Exclude this project from the all target
41 #   NO_INSTALL
42 #     Don't generate install targets for this project
43 #   ALWAYS_CLEAN
44 #     Always clean the sub-project before building
45 #   CMAKE_ARGS arguments...
46 #     Optional cmake arguments to pass when configuring the project
47 #   TOOLCHAIN_TOOLS targets...
48 #     Targets for toolchain tools (defaults to clang;lld)
49 #   DEPENDS targets...
50 #     Targets that this project depends on
51 #   EXTRA_TARGETS targets...
52 #     Extra targets in the subproject to generate targets for
53 #   PASSTHROUGH_PREFIXES prefix...
54 #     Extra variable prefixes (name is always included) to pass down
55 #   STRIP_TOOL path
56 #     Use provided strip tool instead of the default one.
57 #   TARGET_TRIPLE triple
58 #     Optional target triple to pass to the compiler
59 #   )
60 function(llvm_ExternalProject_Add name source_dir)
61   cmake_parse_arguments(ARG
62     "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
63     "SOURCE_DIR"
64     "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES;STRIP_TOOL;TARGET_TRIPLE"
65     ${ARGN})
66   canonicalize_tool_name(${name} nameCanon)
68   foreach(arg ${ARG_CMAKE_ARGS})
69     if(arg MATCHES "^-DCMAKE_SYSTEM_NAME=")
70       string(REGEX REPLACE "^-DCMAKE_SYSTEM_NAME=(.*)$" "\\1" _cmake_system_name "${arg}")
71     endif()
72   endforeach()
74   # If CMAKE_SYSTEM_NAME is not set explicitly in the arguments passed to us,
75   # reflect CMake's own default.
76   if (NOT _cmake_system_name)
77     set(_cmake_system_name "${CMAKE_HOST_SYSTEM_NAME}")
78   endif()
80   if(NOT ARG_TARGET_TRIPLE)
81     set(target_triple ${LLVM_DEFAULT_TARGET_TRIPLE})
82   else()
83     set(target_triple ${ARG_TARGET_TRIPLE})
84   endif()
86   is_msvc_triple(is_msvc_target ${target_triple})
88   if(NOT ARG_TOOLCHAIN_TOOLS)
89     set(ARG_TOOLCHAIN_TOOLS clang)
90     # AIX 64-bit XCOFF and big AR format is not yet supported in some of these tools.
91     if(NOT _cmake_system_name STREQUAL AIX)
92       list(APPEND ARG_TOOLCHAIN_TOOLS lld llvm-ar llvm-ranlib llvm-nm llvm-objdump)
93       if(_cmake_system_name STREQUAL Darwin)
94         list(APPEND ARG_TOOLCHAIN_TOOLS llvm-libtool-darwin llvm-lipo)
95       elseif(is_msvc_target)
96         list(APPEND ARG_TOOLCHAIN_TOOLS llvm-lib llvm-rc)
97         if (LLVM_ENABLE_LIBXML2)
98           list(APPEND ARG_TOOLCHAIN_TOOLS llvm-mt)
99         endif()
100       else()
101         # TODO: These tools don't fully support Mach-O format yet.
102         list(APPEND ARG_TOOLCHAIN_TOOLS llvm-objcopy llvm-strip llvm-readelf)
103       endif()
104     endif()
105   endif()
106   foreach(tool ${ARG_TOOLCHAIN_TOOLS})
107     if(TARGET ${tool})
108       list(APPEND TOOLCHAIN_TOOLS ${tool})
110       # $<TARGET_FILE:tgt> only works on add_executable or add_library targets
111       # The below logic mirrors cmake's own implementation
112       get_target_property(target_type "${tool}" TYPE)
113       if(NOT target_type STREQUAL "OBJECT_LIBRARY" AND
114          NOT target_type STREQUAL "UTILITY" AND
115          NOT target_type STREQUAL "GLOBAL_TARGET" AND
116          NOT target_type STREQUAL "INTERFACE_LIBRARY")
117         list(APPEND TOOLCHAIN_BINS $<TARGET_FILE:${tool}>)
118       endif()
120     endif()
121   endforeach()
123   if(NOT ARG_RUNTIME_LIBRARIES)
124     set(ARG_RUNTIME_LIBRARIES compiler-rt libcxx)
125   endif()
126   foreach(lib ${ARG_RUNTIME_LIBRARIES})
127     if(TARGET ${lib})
128       list(APPEND RUNTIME_LIBRARIES ${lib})
129     endif()
130   endforeach()
132   if(ARG_ALWAYS_CLEAN)
133     set(always_clean clean)
134   endif()
136   if(clang IN_LIST TOOLCHAIN_TOOLS)
137     set(CLANG_IN_TOOLCHAIN On)
138   endif()
140   if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
141     list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
142   endif()
144   set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-stamps/)
145   set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}-bins/)
147   add_custom_target(${name}-clear
148     COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}
149     COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR}
150     COMMENT "Clobbering ${name} build and stamp directories"
151     USES_TERMINAL
152     )
154   # Find all variables that start with a prefix and propagate them through
155   get_cmake_property(variableNames VARIABLES)
157   list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon})
158   foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
159     foreach(variableName ${variableNames})
160       if(variableName MATCHES "^${prefix}")
161         string(REPLACE ";" "|" value "${${variableName}}")
162         list(APPEND PASSTHROUGH_VARIABLES
163           -D${variableName}=${value})
164       endif()
165     endforeach()
166   endforeach()
168   # Populate the non-project-specific passthrough variables
169   foreach(variableName ${LLVM_EXTERNAL_PROJECT_PASSTHROUGH})
170     if(DEFINED ${variableName})
171       if("${${variableName}}" STREQUAL "")
172         set(value "")
173       else()
174         string(REPLACE ";" "|" value "${${variableName}}")
175       endif()
176       list(APPEND PASSTHROUGH_VARIABLES
177         -D${variableName}=${value})
178     endif()
179   endforeach()
181   if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING)
182     if(CLANG_IN_TOOLCHAIN)
183       if(is_msvc_target)
184         set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}
185                           -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}
186                           -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX})
187       else()
188         set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}
189                           -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}
190                           -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX})
191       endif()
192     endif()
193     if(lld IN_LIST TOOLCHAIN_TOOLS)
194       if(is_msvc_target)
195         list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/lld-link${CMAKE_EXECUTABLE_SUFFIX})
196       elseif(NOT _cmake_system_name STREQUAL Darwin)
197         list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/ld.lld${CMAKE_EXECUTABLE_SUFFIX})
198       endif()
199     endif()
200     if(llvm-ar IN_LIST TOOLCHAIN_TOOLS)
201       if(is_msvc_target)
202         list(APPEND compiler_args -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-lib${CMAKE_EXECUTABLE_SUFFIX})
203       else()
204         list(APPEND compiler_args -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar${CMAKE_EXECUTABLE_SUFFIX})
205       endif()
206     endif()
207     if(llvm-libtool-darwin IN_LIST TOOLCHAIN_TOOLS)
208       list(APPEND compiler_args -DCMAKE_LIBTOOL=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-libtool-darwin${CMAKE_EXECUTABLE_SUFFIX})
209     endif()
210     if(llvm-lipo IN_LIST TOOLCHAIN_TOOLS)
211       list(APPEND compiler_args -DCMAKE_LIPO=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-lipo${CMAKE_EXECUTABLE_SUFFIX})
212     endif()
213     if(llvm-ranlib IN_LIST TOOLCHAIN_TOOLS)
214       list(APPEND compiler_args -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX})
215     endif()
216     if(llvm-nm IN_LIST TOOLCHAIN_TOOLS)
217       list(APPEND compiler_args -DCMAKE_NM=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-nm${CMAKE_EXECUTABLE_SUFFIX})
218     endif()
219     if(llvm-objdump IN_LIST TOOLCHAIN_TOOLS)
220       list(APPEND compiler_args -DCMAKE_OBJDUMP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objdump${CMAKE_EXECUTABLE_SUFFIX})
221     endif()
222     if(llvm-objcopy IN_LIST TOOLCHAIN_TOOLS)
223       list(APPEND compiler_args -DCMAKE_OBJCOPY=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objcopy${CMAKE_EXECUTABLE_SUFFIX})
224     endif()
225     if(llvm-strip IN_LIST TOOLCHAIN_TOOLS AND NOT ARG_STRIP_TOOL)
226       list(APPEND compiler_args -DCMAKE_STRIP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-strip${CMAKE_EXECUTABLE_SUFFIX})
227     endif()
228     if(llvm-readelf IN_LIST TOOLCHAIN_TOOLS)
229       list(APPEND compiler_args -DCMAKE_READELF=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-readelf${CMAKE_EXECUTABLE_SUFFIX})
230     endif()
231     if(llvm-mt IN_LIST TOOLCHAIN_TOOLS AND is_msvc_target)
232       list(APPEND compiler_args -DCMAKE_MT=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-mt${CMAKE_EXECUTABLE_SUFFIX})
233     endif()
234     if(llvm-rc IN_LIST TOOLCHAIN_TOOLS AND is_msvc_target)
235       list(APPEND compiler_args -DCMAKE_RC_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-rc${CMAKE_EXECUTABLE_SUFFIX})
236     endif()
237     list(APPEND ARG_DEPENDS ${TOOLCHAIN_TOOLS})
238   endif()
240   if(ARG_STRIP_TOOL)
241     list(APPEND compiler_args -DCMAKE_STRIP=${ARG_STRIP_TOOL})
242   endif()
244   add_custom_command(
245     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
246     DEPENDS ${ARG_DEPENDS}
247     COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt
248     COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir
249     COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
250     COMMENT "Clobbering bootstrap build and stamp directories"
251     )
253   add_custom_target(${name}-clobber
254     DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
256   if(ARG_EXCLUDE_FROM_ALL)
257     set(exclude EXCLUDE_FROM_ALL 1)
258   endif()
260   if(CMAKE_SYSROOT)
261     set(sysroot_arg -DCMAKE_SYSROOT=${CMAKE_SYSROOT})
262   endif()
264   if(CMAKE_CROSSCOMPILING OR _cmake_system_name STREQUAL AIX)
265     set(compiler_args -DCMAKE_ASM_COMPILER=${CMAKE_ASM_COMPILER}
266                       -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
267                       -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
268                       -DCMAKE_LINKER=${CMAKE_LINKER}
269                       -DCMAKE_AR=${CMAKE_AR}
270                       -DCMAKE_RANLIB=${CMAKE_RANLIB}
271                       -DCMAKE_NM=${CMAKE_NM}
272                       -DCMAKE_OBJCOPY=${CMAKE_OBJCOPY}
273                       -DCMAKE_OBJDUMP=${CMAKE_OBJDUMP}
274                       -DCMAKE_STRIP=${CMAKE_STRIP}
275                       -DCMAKE_READELF=${CMAKE_READELF})
276   endif()
277   if(CMAKE_CROSSCOMPILING)
278     set(llvm_config_path ${LLVM_CONFIG_PATH})
280     if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
281       string(REGEX MATCH "^[0-9]+" CLANG_VERSION_MAJOR
282              ${PACKAGE_VERSION})
283       if(DEFINED CLANG_RESOURCE_DIR AND NOT CLANG_RESOURCE_DIR STREQUAL "")
284         set(resource_dir ${LLVM_TOOLS_BINARY_DIR}/${CLANG_RESOURCE_DIR})
285       else()
286         set(resource_dir "${LLVM_LIBRARY_DIR}/clang/${CLANG_VERSION_MAJOR}")
287       endif()
288       set(flag_types ASM C CXX MODULE_LINKER SHARED_LINKER EXE_LINKER)
289       foreach(type ${flag_types})
290         set(${type}_flag -DCMAKE_${type}_FLAGS=-resource-dir=${resource_dir})
291       endforeach()
292       string(REPLACE ";" "|" flag_string "${flag_types}")
293       foreach(arg ${ARG_CMAKE_ARGS})
294         if(arg MATCHES "^-DCMAKE_(${flag_string})_FLAGS")
295           foreach(type ${flag_types})
296             if(arg MATCHES "^-DCMAKE_${type}_FLAGS")
297               string(REGEX REPLACE "^-DCMAKE_${type}_FLAGS=(.*)$" "\\1" flag_value "${arg}")
298               set(${type}_flag "${${type}_flag} ${flag_value}")
299             endif()
300           endforeach()
301         else()
302           list(APPEND cmake_args ${arg})
303         endif()
304       endforeach()
305       foreach(type ${flag_types})
306         list(APPEND cmake_args ${${type}_flag})
307       endforeach()
308     else()
309       set(cmake_args ${ARG_CMAKE_ARGS})
310     endif()
311   else()
312     set(llvm_config_path "$<TARGET_FILE:llvm-config>")
313     set(cmake_args ${ARG_CMAKE_ARGS})
314   endif()
316   if(ARG_TARGET_TRIPLE)
317     list(APPEND compiler_args -DCMAKE_C_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
318     list(APPEND compiler_args -DCMAKE_CXX_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
319     list(APPEND compiler_args -DCMAKE_ASM_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
320   endif()
322   ExternalProject_Add(${name}
323     DEPENDS ${ARG_DEPENDS} llvm-config
324     ${name}-clobber
325     PREFIX ${CMAKE_BINARY_DIR}/projects/${name}
326     SOURCE_DIR ${source_dir}
327     STAMP_DIR ${STAMP_DIR}
328     BINARY_DIR ${BINARY_DIR}
329     ${exclude}
330     CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
331                --no-warn-unused-cli
332                ${compiler_args}
333                -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
334                ${sysroot_arg}
335                -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
336                -DLLVM_CONFIG_PATH=${llvm_config_path}
337                -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
338                -DLLVM_HOST_TRIPLE=${LLVM_HOST_TRIPLE}
339                -DLLVM_HAVE_LINK_VERSION_SCRIPT=${LLVM_HAVE_LINK_VERSION_SCRIPT}
340                -DLLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO=${LLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO}
341                -DLLVM_USE_RELATIVE_PATHS_IN_FILES=${LLVM_USE_RELATIVE_PATHS_IN_FILES}
342                -DLLVM_LIT_ARGS=${LLVM_LIT_ARGS}
343                -DLLVM_SOURCE_PREFIX=${LLVM_SOURCE_PREFIX}
344                -DPACKAGE_VERSION=${PACKAGE_VERSION}
345                -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
346                -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
347                -DCMAKE_EXPORT_COMPILE_COMMANDS=1
348                ${cmake_args}
349                ${PASSTHROUGH_VARIABLES}
350     INSTALL_COMMAND ""
351     STEP_TARGETS configure build
352     BUILD_ALWAYS 1
353     USES_TERMINAL_CONFIGURE 1
354     USES_TERMINAL_BUILD 1
355     USES_TERMINAL_INSTALL 1
356     LIST_SEPARATOR |
357     )
359   if(ARG_USE_TOOLCHAIN)
360     set(force_deps DEPENDS ${TOOLCHAIN_BINS})
361   endif()
363   llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
364   ExternalProject_Add_Step(${name} clean
365     COMMAND ${run_clean}
366     COMMENT "Cleaning ${name}..."
367     DEPENDEES configure
368     ${force_deps}
369     WORKING_DIRECTORY ${BINARY_DIR}
370     EXCLUDE_FROM_MAIN 1
371     USES_TERMINAL 1
372     )
373   ExternalProject_Add_StepTargets(${name} clean)
375   if(ARG_USE_TOOLCHAIN)
376     add_dependencies(${name}-clean ${name}-clobber)
377     set_target_properties(${name}-clean PROPERTIES
378       SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
379   endif()
381   if(NOT ARG_NO_INSTALL)
382     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\)"
383       COMPONENT ${name})
385     add_llvm_install_targets(install-${name}
386                              DEPENDS ${name}
387                              COMPONENT ${name})
388   endif()
390   # Add top-level targets
391   foreach(target ${ARG_EXTRA_TARGETS})
392     if(DEFINED ${target})
393       set(external_target "${${target}}")
394     else()
395       set(external_target "${target}")
396     endif()
397     llvm_ExternalProject_BuildCmd(build_runtime_cmd ${external_target} ${BINARY_DIR})
398     add_custom_target(${target}
399       COMMAND ${build_runtime_cmd}
400       DEPENDS ${name}-configure
401       WORKING_DIRECTORY ${BINARY_DIR}
402       VERBATIM
403       USES_TERMINAL)
404   endforeach()
405 endfunction()