trompeloeil

FORK: Header only C++14 mocking framework
git clone https://git.neptards.moe/u3shit/trompeloeil.git
Log | Files | Refs | README

CMakeLists.txt (10690B)


      1 cmake_minimum_required(VERSION 3.2)
      2 project(trompeloeil)
      3 
      4 option(TROMPELOEIL_INSTALL_DOCS "Install documentation" ON)
      5 
      6 include(GNUInstallDirs)
      7 include(ExternalProject)
      8 include(CMakePackageConfigHelpers)
      9 include(CheckCXXCompilerFlag)
     10 
     11 write_basic_package_version_file(
     12   "${CMAKE_CURRENT_BINARY_DIR}/trompeloeil/trompeloeil-config-version.cmake"
     13   VERSION 41
     14   COMPATIBILITY AnyNewerVersion)
     15 
     16 add_library(trompeloeil INTERFACE)
     17 add_library(trompeloeil::trompeloeil ALIAS trompeloeil)
     18 
     19 set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
     20 
     21 target_include_directories(
     22   trompeloeil
     23   INTERFACE
     24     $<BUILD_INTERFACE:${INCLUDE_DIR}>
     25 )
     26 
     27 target_include_directories(
     28   trompeloeil
     29   INTERFACE
     30     $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
     31 )
     32 
     33 set(MASTER_PROJECT OFF)
     34 if (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
     35   set(MASTER_PROJECT ON)
     36 endif()
     37 
     38 if (MASTER_PROJECT AND CMAKE_BUILD_TYPE MATCHES Debug)
     39 
     40   if (${CXX_STANDARD})
     41     set(CMAKE_CXX_STANDARD ${CXX_STANDARD})
     42   else()
     43     set(CMAKE_CXX_STANDARD 14)
     44   endif()
     45   set(CMAKE_CXX_STANDARD_REQUIRED YES)
     46   set(CMAKE_CXX_EXTENSIONS OFF)
     47 
     48   set(CATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/catch)
     49   if(NOT EXISTS ${CATCH_DIR}/catch.hpp)
     50     if (NOT EXISTS ${CATCH_DIR})
     51       make_directory(${CATCH_DIR})
     52     endif()
     53     file(
     54       DOWNLOAD
     55         https://github.com/catchorg/Catch2/releases/download/v2.9.2/catch.hpp  ${CATCH_DIR}/catch.hpp
     56       STATUS
     57         status
     58       LOG
     59         log
     60     )
     61     list(GET status 0 status_code)
     62     list(GET status 1 status_string)
     63 
     64     if(NOT status_code EQUAL 0)
     65       message(FATAL_ERROR "error downloading catch: ${status_string}"
     66         "${log}")
     67     endif()
     68   endif()
     69 
     70   # Assumptions:
     71   # Clang and GNU compilers run on Linux or Linux-like platforms.
     72   # MSVC compilers run on Windows platforms.
     73 
     74   if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
     75 
     76     set(
     77       LIBCXX_PREFIX_PATH
     78       "/usr/lib/llvm-8"
     79       CACHE
     80       PATH
     81       "Path prefix to libc++"
     82     )
     83 
     84     # Interpret CXX_STDLIB, if specified
     85     if (NOT "${CXX_STDLIB}" STREQUAL "")
     86 
     87       if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
     88 
     89         # Emulate -stdlib for g++
     90         if ("${CXX_STDLIB}" STREQUAL "libc++")
     91 
     92           # Disable standard library and
     93           # set include path to appropriate libc++ headers
     94           string(CONCAT
     95                  LIBCXX_INCLUDE_PATH
     96                  "-isystem"
     97                  "${LIBCXX_PREFIX_PATH}"
     98                  "/include/c++/v1")
     99           string(CONCAT
    100                  STDLIB_COMPILE_FLAGS
    101                  "-nostdinc++"
    102                  " "
    103                  "${LIBCXX_INCLUDE_PATH}")
    104           set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STDLIB_COMPILE_FLAGS}")
    105 
    106         elseif ("${CXX_STDLIB}" STREQUAL "libstdc++")
    107 
    108           # This is the default library for g++, nothing to do.
    109 
    110         else()
    111 
    112           # Unknown CXX_STDLIB option
    113           message(FATAL_ERROR
    114                   "CXX_STDLIB only understands libc++ and libstdc++, not "
    115                   "'${CXX_STDLIB}'")
    116 
    117         endif()
    118 
    119       elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    120 
    121         if (("${CXX_STDLIB}" STREQUAL "libc++") OR
    122             ("${CXX_STDLIB}" STREQUAL "libstdc++"))
    123 
    124           set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=${CXX_STDLIB}")
    125 
    126         else()
    127 
    128           # Unknown CXX_STDLIB option
    129           message(FATAL_ERROR
    130                   "CXX_STDLIB only understands libc++ and libstdc++, not "
    131                   "'${CXX_STDLIB}'")
    132 
    133         endif()
    134 
    135       else()
    136 
    137         message(FATAL_ERROR
    138                 "Only g++ and Clang++ compilers support CXX_STDLIB")
    139 
    140       endif()
    141 
    142     endif()
    143 
    144     if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    145       string(CONCAT
    146              WARN_FLAGS
    147              "-Weverything"
    148              " -Wno-c++98-compat-pedantic"
    149              " -Wno-padded"
    150              " -Wno-weak-vtables"
    151              " -Wno-exit-time-destructors"
    152              " -Wno-global-constructors")
    153 
    154       # Disable for Catch2.
    155       # See <https://github.com/catchorg/Catch2/issues/1456>
    156       check_cxx_compiler_flag("-Wno-extra-semi-stmt" WARN_SEMI_STMT)
    157 
    158       if (WARN_SEMI_STMT)
    159         string(APPEND
    160                WARN_FLAGS
    161                " -Wno-extra-semi-stmt")
    162       endif()
    163 
    164       check_cxx_compiler_flag("-Wno-zero-as-null-pointer-constant" WARN_ZERO_NULL)
    165 
    166       if (WARN_ZERO_NULL)
    167         string(APPEND
    168                WARN_FLAGS
    169                " -Wno-zero-as-null-pointer-constant")
    170       endif()
    171 
    172       # Disable for Catch2.
    173       # See <https://github.com/catchorg/Catch2/issues/578>
    174       check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
    175 
    176       if (WARN_RESERVED_ID)
    177         string(APPEND
    178                WARN_FLAGS
    179                " -Wno-reserved-identifier")
    180       endif()
    181 
    182     elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    183       string(CONCAT
    184              WARN_FLAGS
    185              "-Wall"
    186              " -Wextra"
    187              " -pedantic"
    188              " -Wshadow"
    189              " -Wconversion")
    190         check_cxx_compiler_flag("-Wnonnull" WARN_NONNULL)
    191 
    192         if (WARN_NONNULL)
    193             string(APPEND
    194                     WARN_FLAGS
    195                     " -Wnonnull")
    196         endif()
    197     endif()
    198 
    199     set(WARN_FLAGS "${WARN_FLAGS} -Werror")
    200     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARN_FLAGS}")
    201 
    202     # Default sanitizer target properties.
    203     set(TSAN "-fsanitize=undefined,thread")
    204     set(SSAN "-fsanitize=undefined,address")
    205 
    206     # Exceptions to sanitizer target properties based on compiler and compiler version.
    207     if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    208 
    209       if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.0"))
    210          set(SSAN "-fsanitize=undefined,address -fsanitize-address-use-after-scope")
    211       else()
    212         set(SSAN "-fsanitize=undefined,address")
    213       endif()
    214 
    215     elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    216 
    217       if ((NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8")) AND
    218          (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
    219         set(TSAN "-fsanitize=thread")
    220         set(SSAN "-fsanitize=address")
    221       endif()
    222 
    223     endif()
    224 
    225   endif() # Clang or GNU
    226 
    227   if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    228 
    229     add_compile_options(/W4)
    230     add_compile_options(/bigobj)
    231     add_compile_options(/EHsc)
    232 
    233     check_cxx_compiler_flag(/permissive HAS_PERMISSIVE_FLAG)
    234     if(HAS_PERMISSIVE_FLAG)
    235       add_compile_options(/permissive-)
    236     endif()
    237 
    238   endif() # MSVC
    239 
    240   add_executable(
    241     self_test
    242     EXCLUDE_FROM_ALL
    243     test/compiling_tests.cpp
    244     test/compiling_tests_11.cpp
    245     test/compiling_tests_14.cpp
    246     include/catch2/trompeloeil.hpp)
    247 
    248   target_include_directories(
    249     self_test
    250     PRIVATE
    251     ${CATCH_DIR}
    252   )
    253 
    254   if (SANITIZE AND NOT APPLE)
    255     set_target_properties(
    256       self_test
    257       PROPERTIES
    258         LINK_FLAGS
    259           "${SSAN} -fuse-ld=gold"
    260         COMPILE_FLAGS
    261           ${SSAN}
    262     )
    263   endif()
    264 
    265   target_link_libraries(
    266     self_test
    267     PUBLIC
    268       trompeloeil
    269   )
    270 
    271   find_package(Threads REQUIRED)
    272 
    273   add_executable(
    274     thread_terror
    275     EXCLUDE_FROM_ALL
    276     test/thread_terror.cpp
    277     )
    278 
    279   target_link_libraries(
    280     thread_terror
    281     PUBLIC
    282       trompeloeil
    283       Threads::Threads
    284   )
    285 
    286   if (SANITIZE)
    287     set_target_properties(
    288       thread_terror
    289       PROPERTIES
    290         LINK_FLAGS
    291           ${TSAN}
    292         COMPILE_FLAGS
    293           ${TSAN}
    294     )
    295   endif()
    296 
    297   add_executable(
    298     custom_recursive_mutex
    299     EXCLUDE_FROM_ALL
    300     test/custom_recursive_mutex.cpp
    301   )
    302 
    303   target_link_libraries(
    304     custom_recursive_mutex
    305     PUBLIC
    306     trompeloeil
    307     Threads::Threads
    308   )
    309 
    310   if (SANITIZE AND NOT APPLE)
    311     set_target_properties(
    312       custom_recursive_mutex
    313       PROPERTIES
    314         LINK_FLAGS
    315           "${SSAN} -fuse-ld=gold"
    316         COMPILE_FLAGS
    317           ${SSAN}
    318       )
    319   endif()
    320 
    321   # Linker support for CXX_STDLIB argument
    322   if (NOT ("${CXX_STDLIB}" STREQUAL ""))
    323 
    324     if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    325 
    326       if ("${CXX_STDLIB}" STREQUAL "libc++")
    327 
    328         set(LIBCXX_LIBRARY_PATH "${LIBCXX_PREFIX_PATH}/lib")
    329         set(STDLIB_LINK_FLAGS
    330           -nodefaultlibs
    331           -L${LIBCXX_LIBRARY_PATH}
    332           -Wl,-rpath,${LIBCXX_LIBRARY_PATH}
    333         )
    334         set(STDLIB_LINK_LIBRARIES
    335           "-lc++"
    336           "-lc++abi"
    337           "-lm"
    338           "-lc"
    339           "-lgcc_s"
    340           "-lgcc"
    341         )
    342 
    343         set_target_properties(
    344           self_test
    345           PROPERTIES
    346             LINK_FLAGS
    347               ${STDLIB_LINK_FLAGS}
    348         )
    349 
    350         target_link_libraries(
    351           self_test
    352           PUBLIC
    353             ${STDLIB_LINK_LIBRARIES}
    354         )
    355 
    356         set_target_properties(
    357           thread_terror
    358           PROPERTIES
    359             LINK_FLAGS
    360               ${STDLIB_LINK_FLAGS}
    361         )
    362 
    363         target_link_libraries(
    364           thread_terror
    365           PUBLIC
    366             ${STDLIB_LINK_LIBRARIES}
    367         )
    368 
    369         set_target_properties(
    370           custom_recursive_mutex
    371           PROPERTIES
    372             LINK_FLAGS
    373               ${STDLIB_LINK_FLAGS}
    374         )
    375 
    376         target_link_libraries(
    377           custom_recursive_mutex
    378           PUBLIC
    379             ${STDLIB_LINK_LIBRARIES}
    380         )
    381 
    382       endif()
    383 
    384     endif()
    385 
    386   endif()
    387 
    388   # Shameless hack to get target to work on Windows.
    389   if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    390 
    391     add_custom_target(
    392       run_self_test
    393       COMMAND
    394         ${CMAKE_CURRENT_BINARY_DIR}/self_test
    395       DEPENDS
    396         self_test
    397     )
    398 
    399   else()
    400 
    401     add_custom_target(
    402       run_self_test
    403       COMMAND
    404         ${CMAKE_CURRENT_BINARY_DIR}/Debug/self_test
    405       DEPENDS
    406         self_test
    407     )
    408 
    409   endif()
    410 
    411   if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    412 
    413     add_custom_target(
    414       run_coverage
    415       COMMAND
    416         kcov --skip-solibs --include-pattern=trompeloeil.hpp ./coverage ${CMAKE_CURRENT_BINARY_DIR}/self_test
    417       DEPENDS
    418         self_test
    419     )
    420 
    421   endif()
    422 
    423 endif() # MASTER_PROJECT AND CMAKE_BUILD_TYPE MATCHES Debug
    424 
    425 install(
    426   TARGETS
    427     trompeloeil
    428   EXPORT
    429     trompeloeil-targets
    430   INCLUDES DESTINATION
    431     include
    432 )
    433 
    434 install(
    435   EXPORT
    436     trompeloeil-targets
    437   NAMESPACE
    438     trompeloeil::
    439   DESTINATION
    440     ${CMAKE_INSTALL_LIBDIR}/cmake/trompeloeil
    441 )
    442 install(
    443   FILES
    444     trompeloeil-config.cmake
    445     "${CMAKE_CURRENT_BINARY_DIR}/trompeloeil/trompeloeil-config-version.cmake"
    446   DESTINATION
    447     ${CMAKE_INSTALL_LIBDIR}/cmake/trompeloeil
    448   COMPONENT
    449     Devel
    450 )
    451 
    452 install(
    453   DIRECTORY
    454     include/
    455   DESTINATION
    456     ${CMAKE_INSTALL_INCLUDEDIR}
    457 )
    458 
    459 if(TROMPELOEIL_INSTALL_DOCS)
    460   install(
    461     FILES
    462       LICENSE_1_0.txt
    463     DESTINATION
    464       ${CMAKE_INSTALL_DOCDIR}
    465   )
    466 
    467   install(
    468     DIRECTORY
    469       docs
    470     DESTINATION
    471       ${CMAKE_INSTALL_DOCDIR}
    472   )
    473 endif()