brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.3 KiB · 5220b93 Raw
419 lines · plain
1# This file handles building LLVM runtime sub-projects.2cmake_minimum_required(VERSION 3.20.0)3 4# This file can be used in two ways: the bootstrapping build calls it from5# llvm/runtimes/CMakeLists.txt where we reuse the build tree of the top-level6# build or it can be directly invoked in this directory. In the latter case we7# might be building against a LLVM install tree and might not have a valid build8# tree set up yet. We can detect whether we are using the bootstrapping build9# by checking for the HAVE_LLVM_LIT flag that is passed explicitly to10# llvm_ExternalProject_Add().11if (HAVE_LLVM_LIT)12  message(STATUS "Performing bootstrapping runtimes build.")13else()14  message(STATUS "Performing standalone runtimes build.")15endif()16# Add path for custom and the LLVM build's modules to the CMake module path.17set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")18include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake19  NO_POLICY_SCOPE)20 21include(${LLVM_COMMON_CMAKE_UTILS}/Modules/LLVMVersion.cmake)22 23project(Runtimes C CXX ASM)24set(LLVM_SUBPROJECT_TITLE "Runtimes")25set_property(GLOBAL PROPERTY USE_FOLDERS ON)26 27list(INSERT CMAKE_MODULE_PATH 028  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"29  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"30  "${LLVM_COMMON_CMAKE_UTILS}"31  "${LLVM_COMMON_CMAKE_UTILS}/Modules"32  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake"33  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"34)35 36# We order libraries to mirror roughly how they are layered, except that compiler-rt can depend37# on libc++, so we put it after.38set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;libcxx;compiler-rt;libclc;openmp;offload")39set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc;flang-rt;libsycl;orc-rt")40set(LLVM_ENABLE_RUNTIMES "" CACHE STRING41  "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")42if(LLVM_ENABLE_RUNTIMES STREQUAL "all" )43  set(LLVM_ENABLE_RUNTIMES ${LLVM_DEFAULT_RUNTIMES})44endif()45include(SortSubset)46sort_subset("${LLVM_SUPPORTED_RUNTIMES}" "${LLVM_ENABLE_RUNTIMES}" LLVM_ENABLE_RUNTIMES)47foreach(proj ${LLVM_ENABLE_RUNTIMES})48  set(proj_dir "${CMAKE_CURRENT_SOURCE_DIR}/../${proj}")49  if(IS_DIRECTORY ${proj_dir} AND EXISTS ${proj_dir}/CMakeLists.txt)50    list(APPEND runtimes ${proj_dir})51  else()52    message(FATAL_ERROR "LLVM_ENABLE_RUNTIMES requests ${proj} but directory not found: ${proj_dir}")53  endif()54  string(TOUPPER "${proj}" canon_name)55  STRING(REGEX REPLACE "-" "_" canon_name ${canon_name})56  set(LLVM_EXTERNAL_${canon_name}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${proj}")57endforeach()58 59function(runtime_register_component name)60  set_property(GLOBAL APPEND PROPERTY SUB_COMPONENTS ${name})61endfunction()62 63find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)64find_package(Clang PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)65 66set(LLVM_THIRD_PARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../third-party")67 68# If building standalone by pointing CMake at this runtimes directory,69# LLVM_BINARY_DIR isn't set, find_package(LLVM) will fail and these70# intermediate paths are unset.71if (NOT LLVM_BINARY_DIR)72  set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})73endif()74if (NOT LLVM_FOUND)75  set(LLVM_TOOLS_BINARY_DIR ${LLVM_BINARY_DIR}/bin)76  set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)77  set(LLVM_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})78endif()79 80# This variable makes sure that e.g. llvm-lit is found.81set(LLVM_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)82set(LLVM_CMAKE_DIR ${LLVM_MAIN_SRC_DIR}/cmake/modules)83 84include(CheckLibraryExists)85include(LLVMCheckCompilerLinkerFlag)86include(CheckCCompilerFlag)87include(CheckCXXCompilerFlag)88 89 90# Determine whether we are in the runtimes/runtimes-bins directory of a91# bootstrap build.92set(LLVM_TREE_AVAILABLE OFF)93if (LLVM_LIBRARY_DIR AND LLVM_TOOLS_BINARY_DIR AND PACKAGE_VERSION)94  set(LLVM_TREE_AVAILABLE ON)95endif()96 97if(LLVM_TREE_AVAILABLE)98  # Setting these variables will allow the sub-build to put their outputs into99  # the library and bin directories of the top-level build.100  set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR})101  set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_TOOLS_BINARY_DIR})102else()103  # Use own build directory for artifact output.104  set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}")105  set(LLVM_RUNTIME_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")106endif()107 108# CMake omits default compiler include paths, but in runtimes build, we use109# -nostdinc and -nostdinc++ and control include paths manually so this behavior110# is undesirable. Filtering CMAKE_{LANG}_IMPLICIT_INCLUDE_DIRECTORIES to remove111# paths that are inside the build directory disables this behavior.112#113# See https://gitlab.kitware.com/cmake/cmake/-/issues/19227 for further details.114 115function(filter_prefixed list prefix outvar)116  foreach(str ${list})117    string(FIND "${str}" "${prefix}" out)118    if(NOT "${out}" EQUAL 0)119      list(APPEND result ${str})120    endif()121  endforeach()122  set(${outvar} ${result} PARENT_SCOPE)123endfunction()124 125filter_prefixed("${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}" ${LLVM_BINARY_DIR} CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)126filter_prefixed("${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}" ${LLVM_BINARY_DIR} CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)127filter_prefixed("${CMAKE_ASM_IMPLICIT_INCLUDE_DIRECTORIES}" ${LLVM_BINARY_DIR} CMAKE_ASM_IMPLICIT_INCLUDE_DIRECTORIES)128 129# The compiler driver may be implicitly trying to link against libunwind,130# which might not work if libunwind doesn't exist yet. Try to check if131# --unwindlib=none is supported, and use that if possible.132#133# TODO: Note that this is problematic when LLVM_USE_SANITIZER is used134# because some sanitizers require the unwinder and so the combination of135# -fsanitize=... --unwindlib=none will always result in a linking error.136# Currently, we counteract this issue by adding -fno-sanitize=all flag in137# the project specific code within */cmake/config-ix.cmake files but that's138# brittle. We should ideally move this to runtimes/CMakeLists.txt.139llvm_check_compiler_linker_flag(C "--unwindlib=none" CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG)140if (CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG)141  set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")142  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")143  # TODO: When we can require CMake 3.14, we should use144  # CMAKE_REQUIRED_LINK_OPTIONS here. Until then, we need a workaround:145  # When using CMAKE_REQUIRED_FLAGS, this option gets added both to146  # compilation and linking commands. That causes warnings in the147  # compilation commands during cmake tests. This is normally benign, but148  # when testing whether -Werror works, that test fails (due to the149  # preexisting warning).150  #151  # Therefore, before we can use CMAKE_REQUIRED_LINK_OPTIONS, check if we152  # can use --start-no-unused-arguments to silence the warnings about153  # --unwindlib=none during compilation.154  #155  # We must first add --unwindlib=none to CMAKE_REQUIRED_FLAGS above, to156  # allow this subsequent test to succeed, then rewrite CMAKE_REQUIRED_FLAGS157  # below.158  check_c_compiler_flag("--start-no-unused-arguments" C_SUPPORTS_START_NO_UNUSED_ARGUMENTS)159  if (C_SUPPORTS_START_NO_UNUSED_ARGUMENTS)160    set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS} --start-no-unused-arguments --unwindlib=none --end-no-unused-arguments")161  endif()162endif()163 164# Disable use of the installed C++ standard library when building runtimes.165# Check for -nostdlib++ first; if there's no C++ standard library yet,166# all check_cxx_compiler_flag commands will fail until we add -nostdlib++167# (or -nodefaultlibs).168#169# CMAKE_REQUIRED_FLAGS is used both for C and C++ compilation. This breaks170# compiling with GCC (and we should not need to force -nostd* for GCC anyway),171# so apply it only with Clang. However, since there are cases when appending172# the flag actually breaks the build, still perform the checks rather than173# appending it unconditionally.174#175# TODO: find a better solution. See the discussion on:176# https://github.com/llvm/llvm-project/issues/90332177# https://github.com/llvm/llvm-project/pull/108357178 179if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")180  llvm_check_compiler_linker_flag(CXX "-nostdlib++" CXX_SUPPORTS_NOSTDLIBXX_FLAG)181  if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)182    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")183  endif()184  check_cxx_compiler_flag(-nostdinc++ CXX_SUPPORTS_NOSTDINCXX_FLAG)185  if (CXX_SUPPORTS_NOSTDINCXX_FLAG)186    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdinc++")187  endif()188endif()189 190# The NVPTX target needs to override linking to pass compiler flag checks.191if("${LLVM_RUNTIMES_TARGET}" MATCHES "^nvptx")192  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -flto -c")193endif()194 195# Avoid checking whether the compiler is working.196set(LLVM_COMPILER_CHECKED ON)197 198# Handle common options used by all runtimes.199include(AddLLVM)200include(HandleLLVMOptions)201 202# Loot at the PATH first to avoid a version mismatch between the command-line203# python and the CMake-found version204set(Python3_FIND_REGISTRY LAST)205find_package(Python3 REQUIRED COMPONENTS Interpreter)206 207# Host triple is used by tests to check if they are running natively.208include(GetHostTriple)209get_host_triple(LLVM_HOST_TRIPLE)210message(STATUS "LLVM host triple: ${LLVM_HOST_TRIPLE}")211 212# TODO: We shouldn't be using LLVM_DEFAULT_TARGET_TRIPLE for runtimes since we213# aren't generating code, LLVM_TARGET_TRIPLE is a better fit.214set(LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_HOST_TRIPLE}" CACHE STRING215    "Default target for which the runtimes will be built.")216message(STATUS "LLVM default target triple: ${LLVM_DEFAULT_TARGET_TRIPLE}")217 218set(LLVM_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")219 220if(CMAKE_C_COMPILER_ID MATCHES "Clang")221  set(option_prefix "")222  if (CMAKE_C_SIMULATE_ID MATCHES "MSVC")223    set(option_prefix "/clang:")224  endif()225  set(print_target_triple ${CMAKE_C_COMPILER} ${option_prefix}--target=${LLVM_DEFAULT_TARGET_TRIPLE} ${option_prefix}-print-target-triple)226  execute_process(COMMAND ${print_target_triple}227    RESULT_VARIABLE result228    OUTPUT_VARIABLE output229    OUTPUT_STRIP_TRAILING_WHITESPACE)230  if(result EQUAL 0)231    set(LLVM_DEFAULT_TARGET_TRIPLE ${output})232  else()233    string(REPLACE ";" " " print_target_triple "${print_target_triple}")234    # TODO(#97876): Report an error.235    message(WARNING "Failed to execute `${print_target_triple}` to normalize target triple.")236  endif()237endif()238 239option(LLVM_INCLUDE_TESTS "Generate build targets for the runtimes unit tests." ON)240option(LLVM_INCLUDE_DOCS "Generate build targets for the runtimes documentation." ON)241option(LLVM_ENABLE_SPHINX "Use Sphinx to generate the runtimes documentation." OFF)242option(RUNTIMES_EXECUTE_ONLY_CODE "Compile runtime libraries as execute-only." OFF)243 244if (RUNTIMES_EXECUTE_ONLY_CODE)245  # If a target doesn't support or recognise -mexecute-only, Clang will simply ignore the flag.246  # We can check for this case using -Werror=unused-command-line-argument.247  check_c_compiler_flag("-mexecute-only -Werror=unused-command-line-argument" C_SUPPORTS_MEXECUTE_ONLY)248  if (NOT C_SUPPORTS_MEXECUTE_ONLY)249    message(FATAL_ERROR "RUNTIMES_EXECUTE_ONLY_CODE was turned on, but the target '${LLVM_TARGET_TRIPLE}'"250                        " doesn't support the -mexecute-only flag")251  endif()252 253  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mexecute-only")254  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mexecute-only")255endif()256 257# Use libtool instead of ar if you are both on an Apple host, and targeting Apple.258if(CMAKE_HOST_APPLE AND APPLE)259  include(UseLibtool)260endif()261 262# This can be used to detect whether we're in the runtimes build.263set(LLVM_RUNTIMES_BUILD ON)264 265# Make GTest available to all runtimes266# The runtime must call make_gtest_target() for it to become available. This is267# to avoid build failures when gtest is not actually needed. In particular,268# mingw-incomplete-sysroot is missing C++ header files that GTest needs to269# compile.270function(build_gtest)271  if(TARGET default_gtest)272    # Already available273    return()274  endif()275 276  add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/runtimes_gtest")277endfunction()278 279foreach(entry ${runtimes})280  get_filename_component(projName ${entry} NAME)281 282  # TODO: Clean this up as part of an interface standardization283  string(REPLACE "-" "_" canon_name ${projName})284  string(TOUPPER ${canon_name} canon_name)285 286  # TODO: compiler-rt has to use standalone build for now. We tried to remove287  # this in D57992 but this broke the build because compiler-rt assumes that288  # LLVM and Clang are configured in the same build to set up dependencies. We289  # should clean up the compiler-rt build and remove this eventually.290  if ("${canon_name}" STREQUAL "COMPILER_RT")291    set(${canon_name}_STANDALONE_BUILD ON)292  endif()293 294  if(LLVM_RUNTIMES_LIBDIR_SUBDIR)295    set(${canon_name}_LIBDIR_SUBDIR "${LLVM_RUNTIMES_LIBDIR_SUBDIR}" CACHE STRING "" FORCE)296  endif()297 298  # Setting a variable to let sub-projects detect which other projects299  # will be included under here.300  set(HAVE_${canon_name} ON)301endforeach()302if(LLVM_INCLUDE_TESTS)303  # If built with the runtimes build (rooted at runtimes/CMakeLists.txt), we304  # won't have llvm-lit. If built with the bootstrapping build (rooted at305  # llvm/CMakeLists.txt), the top-level llvm CMake invocation already generated306  # the llvm-lit script.307  if (NOT HAVE_LLVM_LIT)308    # Ensure that the appropriate variables for lit are set before adding any309    # runtimes since their CMake tests configuration might depend on lit being310    # present. This ensures that the testsuites use a local lit from the build311    # dir rather than ${LLVM_INSTALL_DIR}/bin/llvm-lit (which may not exist if312    # LLVM_BINARY_DIR points at an installed LLVM tree rather than a build tree).313    set(LLVM_LIT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin)314    get_llvm_lit_path(_base_dir _file_name ALLOW_EXTERNAL)315    set(LLVM_EXTERNAL_LIT "${_base_dir}/${_file_name}" CACHE STRING "Command used to spawn lit" FORCE)316    # Avoid warning about missing llvm-lit from runtimes CMake files. This is317    # fine since we call configure_file() to create llvm-lit at the end of this318    # file (after recursing into all runtimes' CMake logic), so it will exist.319    set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "")320  endif()321 322  set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported")323  if (MSVC OR XCODE)324    set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")325  endif()326  set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")327 328  umbrella_lit_testsuite_begin(check-runtimes)329endif()330 331# We do this in two loops so that HAVE_* is set for each runtime before the332# other runtimes are added.333foreach(entry ${runtimes})334  get_filename_component(projName ${entry} NAME)335 336  add_subdirectory(${entry} ${projName})337endforeach()338 339# Define runtimes-test-depends so the parent build can use it unconditionally.340add_custom_target(runtimes-test-depends)341 342if(LLVM_INCLUDE_TESTS)343  # LLVM_RUNTIMES_LIT_DEPENDS is populated when lit tests are added between344  # umbrella_list_testsuite begin and end. The bootstrap runtimes builds345  # currently assumes this target exists.346  get_property(LLVM_RUNTIMES_LIT_DEPENDS GLOBAL PROPERTY LLVM_RUNTIMES_LIT_DEPENDS)347  if(LLVM_RUNTIMES_LIT_DEPENDS)348    # add_dependencies complains if called with no dependencies349    add_dependencies(runtimes-test-depends ${LLVM_RUNTIMES_LIT_DEPENDS})350  endif()351  # Add a global check rule now that all subdirectories have been traversed352  # and we know the total set of lit testsuites.353  umbrella_lit_testsuite_end(check-runtimes)354 355  if (NOT HAVE_LLVM_LIT)356    # If built by manually invoking cmake on this directory, we don't have357    # llvm-lit. If invoked via llvm/runtimes, the toplevel llvm cmake358    # invocation already generated the llvm-lit script.359    # NOTE: this must be called after all testsuites have been added, since360    # otherwise the generated llvm-lit does not have all required path mappings.361    add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit362                     ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit)363  endif()364 365  get_property(LLVM_RUNTIMES_LIT_TESTSUITES GLOBAL PROPERTY LLVM_RUNTIMES_LIT_TESTSUITES)366  string(REPLACE ";" "\n" LLVM_RUNTIMES_LIT_TESTSUITES "${LLVM_RUNTIMES_LIT_TESTSUITES}")367  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lit.tests ${LLVM_RUNTIMES_LIT_TESTSUITES})368else()369  # Create empty files so the parent build can use these unconditionally.370  file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/lit.tests)371endif()372 373get_property(SUB_COMPONENTS GLOBAL PROPERTY SUB_COMPONENTS)374if(SUB_COMPONENTS)375  list(REMOVE_DUPLICATES SUB_COMPONENTS)376  foreach(component ${SUB_COMPONENTS})377    if(NOT TARGET ${component})378      message(SEND_ERROR "Missing target for runtime component ${component}!")379      continue()380    endif()381 382    if(TARGET check-${component})383      list(APPEND SUB_CHECK_TARGETS check-${component})384    endif()385 386    if(TARGET install-${component})387      list(APPEND SUB_INSTALL_TARGETS install-${component})388    endif()389  endforeach()390 391  if(LLVM_RUNTIMES_TARGET)392    configure_file(393      ${CMAKE_CURRENT_SOURCE_DIR}/Components.cmake.in394      ${CMAKE_CURRENT_BINARY_DIR}/runtimes/${LLVM_RUNTIMES_TARGET}/Components.cmake)395  else()396    configure_file(397      ${CMAKE_CURRENT_SOURCE_DIR}/Components.cmake.in398      ${CMAKE_CURRENT_BINARY_DIR}/runtimes/Components.cmake)399  endif()400endif()401 402# If the user requested 'compile_commands.json' we merge the generated JSON from403# the created directories.404if(CMAKE_EXPORT_COMPILE_COMMANDS AND NOT ("${LLVM_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}"))405  # Make a dependency so that we don't error if the file gets deleted somehow.406  add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/compile_commands.json407                     COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/compile_commands.json)408 409  file(TO_NATIVE_PATH "${LLVM_MAIN_SRC_DIR}/utils/merge-json.py" MERGE_JSON_PATH)410  add_custom_command(OUTPUT ${LLVM_BINARY_DIR}/compile_commands.json411                     COMMAND ${CMAKE_COMMAND} -E touch ${LLVM_BINARY_DIR}/compile_commands.json412                     COMMAND ${Python3_EXECUTABLE} ${MERGE_JSON_PATH}413                             ${LLVM_BINARY_DIR}/compile_commands.json414                             ${CMAKE_BINARY_DIR}/compile_commands.json415                             -o ${LLVM_BINARY_DIR}/compile_commands.json416                     DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json)417  add_custom_target(merge_runtime_commands ALL DEPENDS ${LLVM_BINARY_DIR}/compile_commands.json)418endif()419