brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.3 KiB · 9235077 Raw
368 lines · plain
1#===-- cmake/modules/AddFlangRT.cmake --------------------------------------===#2#3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4# See https://llvm.org/LICENSE.txt for license information.5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6#7#===------------------------------------------------------------------------===#8 9# Builds a library with common options for Flang-RT.10#11# Usage:12#13# add_flangrt_library(name sources ...14#   SHARED15#     Build a dynamic (.so/.dll) library16#   STATIC17#     Build a static (.a/.lib) library18#   OBJECT19#     Always create an object library.20#     Without SHARED/STATIC, build only the object library.21#   INSTALL_WITH_TOOLCHAIN22#     Install library into Clang's resource directory so it can be found by the23#     Flang driver during compilation, including tests24#   EXCLUDE_FROM_ALL25#     Do not build library by default; typically used for libraries needed for26#     testing only, no install27#   LINK_TO_LLVM28#     Library requires include path and linking to LLVM's Support component29#   ADDITIONAL_HEADERS30#     May specify header files for IDE generators.31#   INCLUDE_DIRECTORIES32#     Additional target_include_directories for all added targets33#   LINK_LIBRARIES34#     Additional target_link_libraries for all added targets35#   TARGET_PROPERTIES36#     Set target properties of all added targets37# )38function (add_flangrt_library name)39  set(options STATIC SHARED OBJECT INSTALL_WITH_TOOLCHAIN EXCLUDE_FROM_ALL LINK_TO_LLVM)40  set(multiValueArgs ADDITIONAL_HEADERS INCLUDE_DIRECTORIES LINK_LIBRARIES TARGET_PROPERTIES)41  cmake_parse_arguments(ARG42    "${options}"43    ""44    "${multiValueArgs}"45    ${ARGN})46 47  if (ARG_INSTALL_WITH_TOOLCHAIN AND ARG_EXCLUDE_FROM_ALL)48    message(SEND_ERROR "add_flangrt_library(${name} ...):49        INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When50        installing an artifact it must have been built first in the 'all' target.51      ")52  endif ()53 54  # Internal names of libraries. If called with just single type option, use55  # the default name for it. Name of targets must only depend on function56  # arguments to be predictable for callers.57  set(name_static "${name}.static")58  set(name_shared "${name}.shared")59  set(name_object "obj.${name}")60  if (ARG_STATIC AND NOT ARG_SHARED)61    set(name_static "${name}")62  elseif (NOT ARG_STATIC AND ARG_SHARED)63    set(name_shared "${name}")64  elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND ARG_OBJECT)65    set(name_object "${name}")66  elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)67    # Only one of them will actually be built.68    set(name_static "${name}")69    set(name_shared "${name}")70  endif ()71 72  # Determine what to build. If not explicitly specified, honor73  # BUILD_SHARED_LIBS (e.g. for unittest libraries). If can build static and74  # shared, use ENABLE_STATIC/ENABLE_SHARED setting.75  if (ARG_STATIC AND ARG_SHARED)76    set(build_static ${FLANG_RT_ENABLE_STATIC})77    set(build_shared ${FLANG_RT_ENABLE_SHARED})78  else ()79    set(build_static ${ARG_STATIC})80    set(build_shared ${ARG_SHARED})81  endif ()82  if (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)83    if (BUILD_SHARED_LIBS)84      set(build_shared ON)85    else ()86      set(build_static ON)87    endif ()88  endif ()89 90  # Build an object library if building multiple libraries at once or if91  # explicitly requested.92  set(build_object OFF)93  if (ARG_OBJECT)94    set(build_object ON)95  elseif (build_static AND build_shared)96    set(build_object ON)97  endif ()98 99  # srctargets: targets that contain source files100  # libtargets: static/shared if they are built101  # alltargets: any add_library target added by this function102  set(srctargets "")103  set(libtargets "")104  set(alltargets "")105  if (build_static)106    list(APPEND srctargets "${name_static}")107    list(APPEND libtargets "${name_static}")108    list(APPEND alltargets "${name_static}")109  endif ()110  if (build_shared)111    list(APPEND srctargets "${name_shared}")112    list(APPEND libtargets "${name_shared}")113    list(APPEND alltargets "${name_shared}")114  endif ()115  if (build_object)116    set(srctargets "${name_object}")117    list(APPEND alltargets "${name_object}")118  endif ()119 120  set(extra_args "")121  if (ARG_EXCLUDE_FROM_ALL)122    list(APPEND extra_args EXCLUDE_FROM_ALL)123  endif ()124 125  # Also add header files to IDEs to list as part of the library.126  set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)127 128  # Create selected library types.129  if (build_object)130    add_library("${name_object}" OBJECT ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})131    set_target_properties(${name_object} PROPERTIES132        POSITION_INDEPENDENT_CODE ON133        FOLDER "Flang-RT/Object Libraries"134      )135 136    # Replace arguments for the libraries we are going to create.137    set(ARG_ADDITIONAL_HEADERS "")138    set(ARG_UNPARSED_ARGUMENTS "$<TARGET_OBJECTS:${name_object}>")139  endif ()140  if (build_static)141    add_library("${name_static}" STATIC ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})142    target_link_libraries("${name_static}" PRIVATE flang-rt-libcxx-headers flang-rt-libc-headers flang-rt-libc-static)143  endif ()144  if (build_shared)145    add_library("${name_shared}" SHARED ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})146    target_link_libraries("${name_shared}" PRIVATE flang-rt-libcxx-headers flang-rt-libc-headers flang-rt-libc-shared)147    if (Threads_FOUND) 148      target_link_libraries(${name_shared} PUBLIC Threads::Threads)149    endif ()150 151    # Special dependencies handling for shared libraries only:152    #153    # flang-rt libraries must not depend on libc++/libstdc++,154    # so set the linker language to C to avoid the unnecessary155    # library dependence. Note that libc++/libstdc++ may still156    # come through CMAKE_CXX_IMPLICIT_LINK_LIBRARIES.157    set_target_properties(${name_shared} PROPERTIES LINKER_LANGUAGE C)158    # Use --as-needed to avoid unnecessary dependencies.159    if (LINKER_AS_NEEDED_OPT)160      target_link_options(${name_shared} BEFORE PRIVATE161          "${LINKER_AS_NEEDED_OPT}"162        )163    endif()164  endif ()165 166  if (libtargets)167    # Provide a default alias which exists in either setting.168    if (BUILD_SHARED_LIBS)169      if (build_shared)170        set(default_target "${name_shared}")171      else ()172        set(default_target "${name_static}")173      endif ()174    else ()175      if (build_static)176        set(default_target "${name_static}")177      else ()178        set(default_target "${name_shared}")179      endif ()180    endif ()181    add_library(${name}.default ALIAS "${default_target}")182 183    # Provide a build target that builds any enabled library.184    # Not intended for target_link_libraries. Either use the ${name}.static,185    # ${name}.shared variants, or ${name}.default to let BUILD_SHARED_LIBS186    # decide.187    if (NOT TARGET ${name})188      add_custom_target(${name})189      add_dependencies(${name} ${libtargets})190    endif ()191  endif ()192 193  foreach (tgtname IN LISTS libtargets)194    if (NOT WIN32)195      # Use same stem name for .a and .so. Common in UNIX environments.196      # Not possible in Windows environments.197      set_target_properties(${tgtname} PROPERTIES OUTPUT_NAME "${name}")198    endif ()199 200    if (ARG_INSTALL_WITH_TOOLCHAIN)201      set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")202    else ()203      set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Libraries")204    endif ()205  endforeach ()206 207 set(TARGET_FLAGS)208  if(APPLE)209    set(DARWIN_EMBEDDED_PLATFORMS)210    set(DARWIN_osx_BUILTIN_MIN_VER 10.7)211    set(DARWIN_osx_BUILTIN_MIN_VER_FLAG212        -mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER})213  endif()214 215  # Define how to compile and link the library.216  # Some conceptionally only apply to ${srctargets} or ${libtargets}, but we217  # apply them to ${alltargets}. In worst case, they are ignored by CMake.218  foreach (tgtname IN LISTS alltargets)219    # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.220    target_compile_features(${tgtname} PRIVATE cxx_std_17)221 222    # When building the flang runtime if LTO is enabled the archive file223    # contains LLVM IR rather than object code. Currently flang is not224    # LTO aware so cannot link this file to compiled Fortran code.225    if (FLANG_RT_HAS_FNO_LTO_FLAG)226      target_compile_options(${tgtname} PRIVATE -fno-lto)227    endif ()228 229    # Use compiler-specific options to disable exceptions and RTTI.230    if (LLVM_COMPILER_IS_GCC_COMPATIBLE)231      target_compile_options(${tgtname} PRIVATE232          $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -funwind-tables -fno-asynchronous-unwind-tables>233        )234 235      # We define our own _GLIBCXX_THROW_OR_ABORT here because, as of236      # GCC 15.1, the libstdc++ header file <bits/c++config> uses237      # (void)_EXC in its definition of _GLIBCXX_THROW_OR_ABORT to238      # silence a warning.239      #240      # This is a problem for us because some compilers, specifically241      # clang, do not always optimize away that (void)_EXC even though242      # it is unreachable since it occurs after a call to243      # _builtin_abort().  Because _EXC is typically an object derived244      # from std::exception, (void)_EXC, when not optimized away,245      # calls std::exception methods defined in the libstdc++ shared246      # library.  We shouldn't link against that library since our247      # build version may conflict with the version used by a hybrid248      # Fortran/C++ application.249      #250      # Redefining _GLIBCXX_THROW_OR_ABORT in this manner is not251      # supported by the maintainers of libstdc++, so future changes252      # to libstdc++ may require future changes to this build script253      # and/or future changes to the Fortran runtime source code.254      target_compile_options(${tgtname} PUBLIC "-D_GLIBCXX_THROW_OR_ABORT(_EXC)=(__builtin_abort())")255    elseif (MSVC)256      target_compile_options(${tgtname} PRIVATE257          $<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->258        )259    elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")260      target_compile_options(${tgtname} PRIVATE261          $<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>262        )263    endif ()264 265    # Add target specific options if necessary.266    if ("${LLVM_RUNTIMES_TARGET}" MATCHES "^amdgcn")267      target_compile_options(${tgtname} PRIVATE268          $<$<COMPILE_LANGUAGE:CXX>:-nogpulib -flto -fvisibility=hidden>269        )270    elseif ("${LLVM_RUNTIMES_TARGET}" MATCHES "^nvptx")271      target_compile_options(${tgtname} PRIVATE272          $<$<COMPILE_LANGUAGE:CXX>:-nogpulib -flto -fvisibility=hidden -Wno-unknown-cuda-version --cuda-feature=+ptx63>273        )274    elseif (APPLE)275      # Clang on Darwin enables non-POSIX extensions by default.276      # This causes some macros to leak, such as HUGE from <math.h>, which277      # causes some conflicts with Flang symbols (but not with Flang-RT, for278      # now).279      # It also causes some Flang-RT extensions to be disabled, such as fdate,280      # that checks for _POSIX_C_SOURCE.281      # Setting _POSIX_C_SOURCE avoids these issues.282      target_compile_options(${tgtname} PRIVATE283          $<$<COMPILE_LANGUAGE:CXX>:${DARWIN_osx_BUILTIN_MIN_VER_FLAG} -D_POSIX_C_SOURCE=200809>284        )285    endif ()286 287    # Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA288    if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")289      # Assuming gcc as host compiler.290      target_compile_options(${tgtname} PRIVATE291          $<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>292        )293    else ()294      # Assuming a clang-compatible CUDA compiler.295      target_compile_options(${tgtname} PRIVATE296          $<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>297        )298    endif ()299 300    # Flang-RT's public headers301    target_include_directories(${tgtname} PUBLIC "${FLANG_RT_SOURCE_DIR}/include")302 303    # For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")304    # User applications can use #include <ISO_Fortran_binding.h>305    target_include_directories(${tgtname} PUBLIC "${FLANG_SOURCE_DIR}/include")306 307    # For Flang-RT's configured config.h to be found308    target_include_directories(${tgtname} PRIVATE "${FLANG_RT_BINARY_DIR}")309 310    # Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS311    # build, to avoid an unwanted dependency on libstdc++/libc++.so.312    target_compile_definitions(${tgtname} PUBLIC _GLIBCXX_NO_ASSERTIONS)313    if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)314      target_compile_options(${tgtname} PUBLIC315          "$<$<COMPILE_LANGUAGE:CXX>:-Wp,-U_GLIBCXX_ASSERTIONS>")316      target_compile_options(${tgtname} PUBLIC317          "$<$<COMPILE_LANGUAGE:CXX>:-Wp,-U_LIBCPP_ENABLE_ASSERTIONS>")318    endif ()319 320    # Non-GTest unittests depend on LLVMSupport321    if (ARG_LINK_TO_LLVM)322      if (LLVM_LINK_LLVM_DYLIB)323        set(llvm_libs LLVM)324      else()325        llvm_map_components_to_libnames(llvm_libs Support)326      endif()327      target_link_libraries(${tgtname} PUBLIC ${llvm_libs})328      target_include_directories(${tgtname} PUBLIC ${LLVM_INCLUDE_DIRS})329    endif ()330 331    if (ARG_INCLUDE_DIRECTORIES)332      target_include_directories(${tgtname} ${ARG_INCLUDE_DIRECTORIES})333    endif ()334 335    if (ARG_LINK_LIBRARIES)336      target_link_libraries(${tgtname} PUBLIC ${ARG_LINK_LIBRARIES})337    endif ()338  endforeach ()339 340  foreach (tgtname IN LISTS libtargets)341    # If this is part of the toolchain, put it into the compiler's resource342    # directory. Otherwise it is part of testing and is not installed at all.343    # TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")344    if (ARG_INSTALL_WITH_TOOLCHAIN)345      set_target_properties(${tgtname}346        PROPERTIES347          ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"348          LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"349        )350 351      install(TARGETS ${tgtname}352          ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"353          LIBRARY DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"354        )355    endif ()356 357    if (ARG_TARGET_PROPERTIES)358      set_target_properties(${tgtname} PROPERTIES ${ARG_TARGET_PROPERTIES})359    endif ()360 361    # flang-rt should build all the Flang-RT targets that are built in an362    # 'all' build.363    if (NOT ARG_EXCLUDE_FROM_ALL)364      add_dependencies(flang-rt ${tgtname})365    endif ()366  endforeach ()367endfunction (add_flangrt_library)368