diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -23,30 +23,16 @@ # Must go below project(..) include(GNUInstallDirs) -if(CLANG_BUILT_STANDALONE) - set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") - set(CMAKE_CXX_STANDARD_REQUIRED YES) - set(CMAKE_CXX_EXTENSIONS NO) - - if(NOT MSVC_IDE) - set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} - CACHE BOOL "Enable assertions") - # Assertions should follow llvm-config's. - mark_as_advanced(LLVM_ENABLE_ASSERTIONS) - endif() - - find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") - list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") - - # Turn into CACHE PATHs for overwritting - set(LLVM_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS} CACHE PATH "Path to llvm/include and any other header dirs needed") - set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}" CACHE PATH "Path to LLVM build tree") - set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") - set(LLVM_TOOLS_BINARY_DIR "${LLVM_TOOLS_BINARY_DIR}" CACHE PATH "Path to llvm/bin") - set(LLVM_LIBRARY_DIR "${LLVM_LIBRARY_DIR}" CACHE PATH "Path to llvm/lib") +# Make sure that our source directory is on the current cmake module path so that +# we can include cmake files from this directory. +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" + "${LLVM_COMMON_CMAKE_UTILS}/Modules" + ) - find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} - NO_DEFAULT_PATH) +if(CLANG_BUILT_STANDALONE) + include(StandaloneBuildHelpers) + require_llvm_utility_binary_path("llvm-tblgen" LLVM_TABLEGEN_EXE) # They are used as destination of target generators. set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) @@ -92,70 +78,23 @@ if(LLVM_INCLUDE_TESTS) find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter) - - # Check prebuilt llvm/utils. - if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} - AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/count${CMAKE_EXECUTABLE_SUFFIX} - AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}) - set(LLVM_UTILS_PROVIDED ON) - endif() - - # Seek installed Lit. - find_program(LLVM_LIT - NAMES llvm-lit lit.py lit - PATHS "${LLVM_MAIN_SRC_DIR}/utils/lit" - DOC "Path to lit.py") - - if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - # Note: path not really used, except for checking if lit was found - if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/llvm-lit) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit utils/llvm-lit) - endif() - if(NOT LLVM_UTILS_PROVIDED) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/FileCheck utils/FileCheck) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/count utils/count) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/not utils/not) - set(LLVM_UTILS_PROVIDED ON) - set(CLANG_TEST_DEPS FileCheck count not) - endif() - set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) - if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h - AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} - AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) - add_subdirectory(${UNITTEST_DIR} third-party/unittest) - endif() - endif() - - if(LLVM_LIT) - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LIT_ARGS_DEFAULT "-sv") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - - get_errc_messages(LLVM_LIT_ERRC_MESSAGES) - - # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. - if( WIN32 AND NOT CYGWIN ) - set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") - endif() - else() - set(LLVM_INCLUDE_TESTS OFF) + find_external_lit() + set_lit_defaults() + require_llvm_utility_binary_path("FileCheck") + require_llvm_utility_binary_path("count") + require_llvm_utility_binary_path("not") + + set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) + if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h + AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} + AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) + add_subdirectory(${UNITTEST_DIR} third-party/unittest) endif() umbrella_lit_testsuite_begin(check-all) endif() # LLVM_INCLUDE_TESTS endif() # standalone -# Make sure that our source directory is on the current cmake module path so that -# we can include cmake files from this directory. -list(INSERT CMAKE_MODULE_PATH 0 - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" - "${LLVM_COMMON_CMAKE_UTILS}/Modules" - ) - # This allows disabling clang's XML dependency even if LLVM finds libxml2. # By default, clang depends on libxml2 if LLVM does. option(CLANG_ENABLE_LIBXML2 "Whether libclang may depend on libxml2" diff --git a/cmake/Modules/StandaloneBuildHelpers.cmake b/cmake/Modules/StandaloneBuildHelpers.cmake new file mode 100644 --- /dev/null +++ b/cmake/Modules/StandaloneBuildHelpers.cmake @@ -0,0 +1,123 @@ +# This file provides helper functions and macros for projects that can be built +# in standalone mode which you often find in linux packaging situations. +# We also noticed that most functions set a bunch of variables in the same way +# by default, so we do this while including this file. + +include_guard() + +# WARNING: The functions in this file only makes sense when building in standalone mode. +# Therefore it raises a FATAL_ERROR if you're using it in some other +# context. +# TODO: Add the XXX_STANDALONE check for anything that is missing here. +if (NOT (CLANG_BUILT_STANDALONE + OR LLD_BUILT_STANDALONE + OR COMPILER_RT_STANDALONE_BUILD + OR OPENMP_STANDALONE_BUILD + OR MLIR_STANDALONE_BUILD + OR LLDB_BUILT_STANDALONE)) + message(FATAL_ERROR "Make sure you build in standalone mode") +endif() + +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") +set(CMAKE_CXX_STANDARD_REQUIRED YES) +set(CMAKE_CXX_EXTENSIONS NO) + +if(NOT MSVC_IDE) +set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} + CACHE BOOL "Enable assertions") +# Assertions should follow llvm-config's. +mark_as_advanced(LLVM_ENABLE_ASSERTIONS) +endif() + +# NOTE: The reason to first run `find_package(LLVM)` is that all the imported +# executables in LLVMExports.cmake are checked for existence. This saves +# us from checking for them ourselves. +find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") +list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") + +# Turn into CACHE PATHs for overwritting +set(LLVM_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS} CACHE PATH "Path to llvm/include and any other header dirs needed") +set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}" CACHE PATH "Path to LLVM build tree") +set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") +set(LLVM_TOOLS_BINARY_DIR "${LLVM_TOOLS_BINARY_DIR}" CACHE PATH "Path to llvm/bin") +set(LLVM_LIBRARY_DIR "${LLVM_LIBRARY_DIR}" CACHE PATH "Path to llvm/lib") + +# Automatically add the current source and build directories to the include path. +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +# This function tries to get the path to the installed utility binary. +# +# - utility: The utility's target name to look up (e.g. FileCheck). If it does +# not exist, or if the imported location points to non-existing file +# a FATAL_ERROR is raised. +# +# - (optional) out_var: The variable with this name is set in the caller's +# scope to hold the path to the utility binary. +# +# NOTE: Check the add_llvm_utility macro in AddLLVM.cmake to find out about how +# utilities are added. They get added to a global list property +# LLVM_EXPORTS which ends up in a file LLVMExports.cmake that is +# installed with LLVM. Your utility target must be defined there. +function(require_llvm_utility_binary_path utility) + # The target of the utility has to exist be it imported or from the build + # tree. + if (NOT TARGET ${utility}) + message(FATAL_ERROR "The utility with the following target name does not exist: \"${utility}\".") + endif() + + if (NOT IMPORTED ${utility}) + message(FATAL_ERROR "We can only get the binary path to an imported target and this target is not imported: ${utility}") + endif() + + set(_imploc IMPORTED_LOCATION_NOCONFIG) + # Based on the build type that the installed LLVM was built with, + # we pick the right import location. + if (LLVM_BUILD_TYPE STREQUAL "Release") + set(_imploc IMPORTED_LOCATION_RELEASE) + elseif (LLVM_BUILD_TYPE STREQUAL "Debug") + set(_imploc IMPORTED_LOCATION_DEBUG) + elseif (LLVM_BUILD_TYPE STREQUAL "RelWithDebInfo") + set(_imploc IMPORTED_LOCATION_RELWITHDEBINFO) + elseif (LLVM_BUILD_TYPE STREQUAL "MinSize") + set(_imploc IMPORTED_LOCATION_MINSIZE) + endif() + get_target_property(util_path "${utility}" ${_imploc}) + + if (NOT EXISTS ${util_path}) + message(FATAL_ERROR "This file for the target '${utility}' does not exist: ${util_path}") + endif() + + if (DEFINED ARGV1) + set(out_var ${ARGV1}) + set(${out_var} "${util_path}" PARENT_SCOPE) + endif() +endfunction() + +# The set_lit_defaults macro exists because the code existed in multiple +# locations before. +macro(set_lit_defaults) + set(LIT_ARGS_DEFAULT "-sv") + if (MSVC OR XCODE) + set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") + endif() + set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") + + get_errc_messages(LLVM_LIT_ERRC_MESSAGES) + set(LLVM_LIT_ERRC_MESSAGES ${LLVM_LIT_ERRC_MESSAGES}) + + # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. + if( WIN32 AND NOT CYGWIN ) + set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") + endif() +endmacro() + +# The find_external_lit macro ensured the variable LLVM_EXTERNAL_LIT is defined +# and points to an existing file. +macro(find_external_lit) + if (NOT DEFINED LLVM_EXTERNAL_LIT) + message(FATAL_ERROR "In standalone build mode you MUST configure with -DLLVM_EXTERNAL_LIT=... pointing to your lit binary") + endif() + if (NOT EXISTS ${LLVM_EXTERNAL_LIT}) + message(FATAL_ERROR "Failed to find external lit at place pointed to by LLVM_EXTERNAL_LIT variable: ${LLVM_EXTERNAL_LIT}") + endif() +endmacro() diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt --- a/lld/CMakeLists.txt +++ b/lld/CMakeLists.txt @@ -23,23 +23,16 @@ # Must go below project(..) include(GNUInstallDirs) -if(LLD_BUILT_STANDALONE) - set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") - set(CMAKE_CXX_STANDARD_REQUIRED YES) - set(CMAKE_CXX_EXTENSIONS NO) - - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") - list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") - - # Turn into CACHE PATHs for overwritting - set(LLVM_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS} CACHE PATH "Path to llvm/include and any other header dirs needed") - set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}" CACHE PATH "Path to LLVM build tree") - set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") +# Make sure that our source directory is on the current cmake module path so that +# we can include cmake files from this directory. +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" + "${LLVM_COMMON_CMAKE_UTILS}/Modules" + ) - find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} - NO_DEFAULT_PATH) +if(LLD_BUILT_STANDALONE) + include(StandaloneBuildHelpers) + require_llvm_utility_binary_path("llvm-tblgen" LLVM_TABLEGEN_EXE) # They are used as destination of target generators. set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) @@ -59,53 +52,17 @@ if(LLVM_INCLUDE_TESTS) find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter) - - # Check prebuilt llvm/utils. - if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} - AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}) - set(LLVM_UTILS_PROVIDED ON) - endif() - - if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - # Note: path not really used, except for checking if lit was found - set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - if(NOT LLVM_UTILS_PROVIDED) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/FileCheck utils/FileCheck) - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/not utils/not) - set(LLVM_UTILS_PROVIDED ON) - set(LLD_TEST_DEPS FileCheck not) - endif() - set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) - if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h - AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} - AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) - add_subdirectory(${UNITTEST_DIR} third-party/unittest) - endif() - else() - # Seek installed Lit. - find_program(LLVM_LIT - NAMES llvm-lit lit.py lit - PATHS "${LLVM_MAIN_SRC_DIR}/utils/lit" - DOC "Path to lit.py") - endif() - - if(LLVM_LIT) - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LIT_ARGS_DEFAULT "-sv") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - - get_errc_messages(LLVM_LIT_ERRC_MESSAGES) - - # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. - if(WIN32 AND NOT CYGWIN) - set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") - endif() - else() - set(LLVM_INCLUDE_TESTS OFF) + find_external_lit() + set_lit_defaults() + require_llvm_utility_binary_path("FileCheck") + require_llvm_utility_binary_path("count") + require_llvm_utility_binary_path("not") + + set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) + if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h + AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} + AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) + add_subdirectory(${UNITTEST_DIR} third-party/unittest) endif() endif() @@ -153,12 +110,6 @@ "`CMakeFiles'. Please delete them.") endif() -# Add path for custom modules. -list(INSERT CMAKE_MODULE_PATH 0 - "${LLD_SOURCE_DIR}/cmake/modules" - "${LLVM_COMMON_CMAKE_UTILS}/Modules" - ) - include(AddLLD) option(LLD_USE_VTUNE