Home | History | Annotate | Download | only in modules
      1 include(ExternalProject)
      2 
      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   if (CMAKE_GENERATOR MATCHES "Make")
      7     # Use special command for Makefiles to support parallelism.
      8     set(${out_var} "$(MAKE)" "-C" "${BINARY_DIR}" "${target}" PARENT_SCOPE)
      9   else()
     10     set(${out_var} ${CMAKE_COMMAND} --build ${bin_dir} --target ${target}
     11                                     --config $<CONFIGURATION> PARENT_SCOPE)
     12   endif()
     13 endfunction()
     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 #   ALWAYS_CLEAN
     23 #     Always clean the sub-project before building
     24 #   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
     32 #   PASSTHROUGH_PREFIXES prefix...
     33 #     Extra variable prefixes (name is always included) to pass down
     34 #   )
     35 function(llvm_ExternalProject_Add name source_dir)
     36   cmake_parse_arguments(ARG
     37     "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
     38     "SOURCE_DIR"
     39     "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES"
     40     ${ARGN})
     41   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 
     61   if(ARG_ALWAYS_CLEAN)
     62     set(always_clean clean)
     63   endif()
     64 
     65   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 
     74   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"
     81     USES_TERMINAL
     82     )
     83 
     84   # Find all variables that start with a prefix and propagate them through
     85   get_cmake_property(variableNames VARIABLES)
     86 
     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()
     96   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)
    119     set(exclude EXCLUDE_FROM_ALL 1)
    120   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}
    133                -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}
    139                ${ARG_CMAKE_ARGS}
    140                ${PASSTHROUGH_VARIABLES}
    141     INSTALL_COMMAND ""
    142     STEP_TARGETS configure build
    143     BUILD_ALWAYS 1
    144     USES_TERMINAL_CONFIGURE 1
    145     USES_TERMINAL_BUILD 1
    146     USES_TERMINAL_INSTALL 1
    147     )
    148 
    149   if(ARG_USE_TOOLCHAIN)
    150     set(force_deps DEPENDS ${TOOLCHAIN_BINS})
    151   endif()
    152 
    153   llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
    154   ExternalProject_Add_Step(${name} clean
    155     COMMAND ${run_clean}
    156     COMMENT "Cleaning ${name}..."
    157     DEPENDEES configure
    158     ${force_deps}
    159     WORKING_DIRECTORY ${BINARY_DIR}
    160     EXCLUDE_FROM_MAIN 1
    161     USES_TERMINAL 1
    162     )
    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"
    180                       USES_TERMINAL)
    181   endif()
    182 
    183   # Add top-level targets
    184   foreach(target ${ARG_EXTRA_TARGETS})
    185     llvm_ExternalProject_BuildCmd(build_runtime_cmd ${target} ${BINARY_DIR})
    186     add_custom_target(${target}
    187       COMMAND ${build_runtime_cmd}
    188       DEPENDS ${name}-configure
    189       WORKING_DIRECTORY ${BINARY_DIR}
    190       VERBATIM
    191       USES_TERMINAL)
    192   endforeach()
    193 endfunction()
    194