Index: llvm/trunk/.gitignore =================================================================== --- llvm/trunk/.gitignore +++ llvm/trunk/.gitignore @@ -46,6 +46,8 @@ projects/* !projects/*.* !projects/Makefile +runtimes/* +!runtimes/*.* # Clang, which is tracked independently. tools/clang # LLDB, which is tracked independently. Index: llvm/trunk/CMakeLists.txt =================================================================== --- llvm/trunk/CMakeLists.txt +++ llvm/trunk/CMakeLists.txt @@ -732,6 +732,8 @@ add_subdirectory(tools) endif() +add_subdirectory(runtimes) + if( LLVM_INCLUDE_EXAMPLES ) add_subdirectory(examples) endif() @@ -742,7 +744,8 @@ llvm_ExternalProject_Add(test-suite ${LLVM_MAIN_SRC_DIR}/projects/test-suite USE_TOOLCHAIN EXCLUDE_FROM_ALL - NO_INSTALL) + NO_INSTALL + ALWAYS_CLEAN) endif() add_subdirectory(test) add_subdirectory(unittests) Index: llvm/trunk/cmake/modules/LLVMExternalProjectUtils.cmake =================================================================== --- llvm/trunk/cmake/modules/LLVMExternalProjectUtils.cmake +++ llvm/trunk/cmake/modules/LLVMExternalProjectUtils.cmake @@ -19,6 +19,8 @@ # Exclude this project from the all target # NO_INSTALL # Don't generate install targets for this project +# ALWAYS_CLEAN +# Always clean the sub-project before building # CMAKE_ARGS arguments... # Optional cmake arguments to pass when configuring the project # TOOLCHAIN_TOOLS targets... @@ -27,11 +29,15 @@ # Targets that this project depends on # EXTRA_TARGETS targets... # Extra targets in the subproject to generate targets for +# PASSTHROUGH_PREFIXES prefix... +# Extra variable prefixes (name is always included) to pass down # ) function(llvm_ExternalProject_Add name source_dir) - cmake_parse_arguments(ARG "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL" + cmake_parse_arguments(ARG + "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN" "SOURCE_DIR" - "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS" ${ARGN}) + "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES" + ${ARGN}) canonicalize_tool_name(${name} nameCanon) if(NOT ARG_TOOLCHAIN_TOOLS) set(ARG_TOOLCHAIN_TOOLS clang lld) @@ -52,6 +58,10 @@ endif() endforeach() + if(ARG_ALWAYS_CLEAN) + set(always_clean clean) + endif() + list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG) if(FOUND_CLANG GREATER -1) set(CLANG_IN_TOOLCHAIN On) @@ -71,15 +81,18 @@ USES_TERMINAL ) - # Find all variables that start with COMPILER_RT and populate a variable with - # them. + # Find all variables that start with a prefix and propagate them through get_cmake_property(variableNames VARIABLES) - foreach(variableName ${variableNames}) - if(variableName MATCHES "^${nameCanon}") - string(REPLACE ";" "\;" value "${${variableName}}") - list(APPEND PASSTHROUGH_VARIABLES - -D${variableName}=${value}) - endif() + + list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon}) + foreach(prefix ${ARG_PASSTHROUGH_PREFIXES}) + foreach(variableName ${variableNames}) + if(variableName MATCHES "^${prefix}") + string(REPLACE ";" "\;" value "${${variableName}}") + list(APPEND PASSTHROUGH_VARIABLES + -D${variableName}=${value}) + endif() + endforeach() endforeach() if(ARG_USE_TOOLCHAIN) @@ -117,6 +130,12 @@ CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS} ${compiler_args} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR} + -DLLVM_CONFIG_PATH=$ + -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR} + -DPACKAGE_VERSION=${PACKAGE_VERSION} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} ${ARG_CMAKE_ARGS} ${PASSTHROUGH_VARIABLES} INSTALL_COMMAND "" @@ -138,6 +157,7 @@ DEPENDEES configure ${force_deps} WORKING_DIRECTORY ${BINARY_DIR} + EXCLUDE_FROM_MAIN 1 USES_TERMINAL 1 ) ExternalProject_Add_StepTargets(${name} clean) Index: llvm/trunk/runtimes/CMakeLists.txt =================================================================== --- llvm/trunk/runtimes/CMakeLists.txt +++ llvm/trunk/runtimes/CMakeLists.txt @@ -0,0 +1,90 @@ +# This file handles building LLVM runtime sub-projects. + +# Runtimes are different from tools or other drop-in projects because runtimes +# should be built with the LLVM toolchain from the build directory. This file is +# a first step to formalizing runtime build interfaces. + +# In the current state this file only works with compiler-rt, other runtimes +# will work as the runtime build interface standardizes. + +# Find all subdirectories containing CMake projects +file(GLOB entries *) +foreach(entry ${entries}) + if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt) + list(APPEND runtimes ${entry}) + endif() +endforeach() + +# If this file is acting as a top-level CMake invocation, this code path is +# triggered by the external project call for the runtimes target below. +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) + + cmake_minimum_required(VERSION 3.4.3) + + # Add the root project's CMake modules, and the LLVM build's modules to the + # CMake module path. + list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/../cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules" + "${LLVM_BINARY_DIR}/lib/cmake/llvm" + ) + + # LLVMConfig.cmake contains a bunch of CMake variables from the LLVM build. + # This file is installed as part of LLVM distributions, so this can be used + # either from a build directory or an installed LLVM. + include(LLVMConfig) + + # Setting these variables will allow the sub-build to put their outputs into + # the library and bin directories of the top-level build. + set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR}) + set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_BINARY_DIR}) + + foreach(entry ${runtimes}) + get_filename_component(projName ${entry} NAME) + + # TODO: Clean this up as part of an interface standardization + string(REPLACE "-" "_" canon_name ${projName}) + string(TOUPPER ${canon_name} canon_name) + # The subdirectories need to treat this as standalone builds + set(${canon_name}_STANDALONE_BUILD On) + + add_subdirectory(${projName}) + endforeach() + +else() # if this is included from LLVM's CMake + include(LLVMExternalProjectUtils) + + # If compiler-rt is present we need to build the builtin libraries first. This + # is required because the other runtimes need the builtin libraries present + # before the just-built compiler can pass the configuration tests. + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt) + llvm_ExternalProject_Add(builtins + ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt/lib/builtins + PASSTHROUGH_PREFIXES COMPILER_RT + USE_TOOLCHAIN) + set(deps builtins) + endif() + + # We create a list the names of all the runtime projects in all uppercase and + # with dashes turned to underscores. This gives us the CMake variable prefixes + # for all variables that will apply to runtimes. + foreach(entry ${runtimes}) + get_filename_component(projName ${entry} NAME) + string(REPLACE "-" "_" canon_name ${projName}) + string(TOUPPER ${canon_name} canon_name) + list(APPEND prefixes ${canon_name}) + endforeach() + + if(runtimes) + # Create a runtimes target that uses this file as its top-level CMake file. + # The runtimes target is a configuration of all the runtime libraries + # together in a single CMake invocaiton. + llvm_ExternalProject_Add(runtimes + ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${deps} llvm-config + # Builtins were built separately above + CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=Off + PASSTHROUGH_PREFIXES ${prefixes} + USE_TOOLCHAIN) + endif() +endif()