CMakeLists.txt 6.4 KB
Newer Older
steinbac's avatar
steinbac committed
1
# cmake compatibility issues
steinbac's avatar
steinbac committed
2
CMAKE_MINIMUM_REQUIRED(VERSION 3.8)
steinbac's avatar
steinbac committed
3 4 5 6 7 8 9 10 11 12

# project name
PROJECT(compass CXX)

# this project is C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
13
include(CheckSymbolExists)
14
include(CheckCXXSourceCompiles)
steinbac's avatar
steinbac committed
15 16 17 18 19 20 21 22 23 24 25 26

# Project information
SET (COMPASS_NAME "Compass - drop-in header-only C++ library to detect hardware capabilities at runtime and at compiletime")
SET (COMPASS_CODENAME "${PROJECT_NAME}")
SET (COMPASS_COPYRIGHT_YEARS "2017")
SET (COMPASS_VERSION_MAJOR 0)
SET (COMPASS_VERSION_MINOR 0)
SET (COMPASS_VERSION_PATCH 0)
SET (COMPASS_VERSION "${COMPASS_VERSION_MAJOR}.${COMPASS_VERSION_MINOR}.${COMPASS_VERSION_PATCH}")
SET (COMPASS_VENDOR_ID "psteinb")
SET (COMPASS_ID "${COMPASS_VENDOR_ID}.${PROJECT_NAME}")

27 28
option(WITH_CXX11_ABI       "enable _GLIBCXX_USE_CXX11_ABI in GCC 5.0+" ON)
option(WITH_TESTS           "enable unit tests" ON)
steinbac's avatar
steinbac committed
29 30 31 32 33 34
option(WITH_SINGLE_HEADER   "use single header file from single-header/" OFF)
option(GENERATE_SINGLE_HEADER   "run pcpp on include/ and produce single-header" OFF)

if(GENERATE_SINGLE_HEADER)
  set(WITH_SINGLE_HEADER ON CACHED)
endif()
35

steinbac's avatar
steinbac committed
36 37
check_cxx_compiler_flag(-Wl,-Bsymbolic HAS_BSYMBOLIC_COMPILERFLAG)
check_cxx_compiler_flag("-Xclang -march=native" HAS_XCLANG_COMPILERFLAG)
steinbac's avatar
steinbac committed
38 39
check_cxx_compiler_flag("-march=native" HAS_MARCH_COMPILERFLAG)
check_cxx_compiler_flag("-xHost" HAS_XHOST_COMPILERFLAG)
steinbac's avatar
steinbac committed
40 41
check_cxx_compiler_flag(-Wall HAS_WALL_COMPILERFLAG)
check_cxx_compiler_flag(-ggdb HAS_GGDB_COMPILERFLAG)
42 43 44 45 46 47 48 49 50 51 52 53 54 55

set(CXX11_CODE_EXAMPLE "\
#include <string>\n\
\
int main(int argc,char** argv){std::string msg;return msg.size();}")
set(CMAKE_REQUIRED_LIBRARIES -lc++ -lc++abi)
CHECK_CXX_SOURCE_COMPILES("${CXX11_CODE_EXAMPLE}" COMPILES_WITH_LIBCXX)
set(CMAKE_REQUIRED_LIBRARIES -lstdc++)
CHECK_CXX_SOURCE_COMPILES("${CXX11_CODE_EXAMPLE}" COMPILES_WITH_LIBSTDCXX)
unset(CMAKE_REQUIRED_LIBRARIES)
CHECK_CXX_SOURCE_COMPILES("${CXX11_CODE_EXAMPLE}" COMPILES_WITH_NO_EXTRAL)

check_cxx_compiler_flag(-lc++ HAS_LIBCXX_COMPILERFLAG)
check_cxx_compiler_flag(-lc++abi HAS_LIBCXXABI_COMPILERFLAG)
steinbac's avatar
steinbac committed
56 57 58 59 60
check_cxx_compiler_flag(-ggdb3 HAS_GGDB3_COMPILERFLAG)
check_cxx_compiler_flag(-O3 HAS_O3_COMPILERFLAG)
check_cxx_compiler_flag(/Oi HAS_OI_COMPILERFLAG)
check_cxx_compiler_flag(-Wno-overflow HAS_WNOOVERFLOW_COMPILERFLAG)

steinbac's avatar
steinbac committed
61 62 63 64 65 66 67 68 69 70 71 72

set(COMPASS_TARGET_NAME               ${PROJECT_NAME})
set(COMPASS_CONFIG_INSTALL_DIR        "lib/cmake/${PROJECT_NAME}"
  CACHE INTERNAL "")
set(COMPASS_INCLUDE_INSTALL_DIR       "include")
set(COMPASS_TARGETS_EXPORT_NAME       "${PROJECT_NAME}Targets")
set(COMPASS_CMAKE_CONFIG_TEMPLATE     "cmake/config.cmake.in")
set(COMPASS_CMAKE_CONFIG_DIR          "${CMAKE_CURRENT_BINARY_DIR}")
set(COMPASS_CMAKE_VERSION_CONFIG_FILE "${COMPASS_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(COMPASS_CMAKE_PROJECT_CONFIG_FILE "${COMPASS_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake")
set(COMPASS_CMAKE_PROJECT_TARGETS_FILE "${COMPASS_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake")

steinbac's avatar
steinbac committed
73

steinbac's avatar
steinbac committed
74
if (NOT WITH_SINGLE_HEADER)
steinbac's avatar
steinbac committed
75
    set(COMPASS_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include")
steinbac's avatar
steinbac committed
76 77
    message(STATUS "Using the multi-header code from ${COMPASS_INCLUDE_BUILD_DIR}")
else()
steinbac's avatar
steinbac committed
78
    set(COMPASS_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/single_include")
steinbac's avatar
steinbac committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92
    message(STATUS "Using the single-header code from ${COMPASS_INCLUDE_BUILD_DIR}")
endif()

add_library(${COMPASS_TARGET_NAME} INTERFACE)
add_library(${PROJECT_NAME}::${COMPASS_TARGET_NAME} ALIAS ${COMPASS_TARGET_NAME})
target_include_directories(
    ${COMPASS_TARGET_NAME}
    INTERFACE
    $<BUILD_INTERFACE:${COMPASS_INCLUDE_BUILD_DIR}>
    $<INSTALL_INTERFACE:include>
)
target_compile_definitions(${COMPASS_TARGET_NAME}
  INTERFACE LIBRARY_HEADER_ONLY
  INTERFACE cxx_std_11
93
  )
steinbac's avatar
steinbac committed
94

steinbac's avatar
steinbac committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
## ============== generate single-header ================
 if (${GENERATE_SINGLE_HEADER})
  find_program(PCPP NAMES pcpp PATH ${PCPP_PATH} PATH_SUFFIXES bin NO_DEFAULT_PATH)
  find_program(PCPP NAMES pcpp)
  if(EXISTS ${PCPP})
    message(STATUS "pcpp found at ${PCPP}")
    if(NOT EXISTS ${COMPASS_INCLUDE_BUILD_DIR})
      file(MAKE_DIRECTORY ${COMPASS_INCLUDE_BUILD_DIR})
      message("created ${COMPASS_INCLUDE_BUILD_DIR}")
    endif()

    execute_process(COMMAND ${PCPP} -o ${COMPASS_INCLUDE_BUILD_DIR}/compass.hpp --line-directive --passthru-defines --passthru-unfound-includes --passthru-unknown-exprs ${PROJECT_SOURCE_DIR}/include/compass.hpp
      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
      RESULT_VARIABLE PCPP_RESULT)
    if(${PCPP_RESULT} EQUAL 0)
      message(STATUS "Preprocessed ${PROJECT_SOURCE_DIR}/include/compass.hpp into ${COMPASS_INCLUDE_BUILD_DIR}/compass.hpp")
    else()
      message(FATAL_ERROR "Preprocessing ${PROJECT_SOURCE_DIR}/include/compass.hpp into ${COMPASS_INCLUDE_BUILD_DIR}/compass.hpp failed")
    endif()
  else()
    message(FATAL_ERROR "pcpp not found (${PCPP_PATH} ${PCPP_FOUND}), unable to continue in single-header configuration")
  endif()
endif()

steinbac's avatar
steinbac committed
119 120 121
#target_sources(compass INTERFACE include/compass.hpp)


122
IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
123
  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.0")
124 125
    set(WITH_CXX11_ABI ON)
  endif()
steinbac's avatar
steinbac committed
126

127
  if(${WITH_CXX11_ABI})
steinbac's avatar
steinbac committed
128
    set(CXX11_ABI_VALUE 1)
129
  else()
steinbac's avatar
steinbac committed
130
    set(CXX11_ABI_VALUE 0)
131
  endif()
steinbac's avatar
steinbac committed
132 133

  target_compile_definitions(${COMPASS_TARGET_NAME} INTERFACE -D_GLIBCXX_USE_CXX11_ABI=${CXX11_ABI_VALUE})
134
  message(">> [${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}] adding -D_GLIBCXX_USE_CXX11_ABI=${CXX11_ABI_VALUE}")
135
endif()
steinbac's avatar
steinbac committed
136

137

138
IF(NOT WIN32)
steinbac's avatar
steinbac committed
139 140
  check_symbol_exists(__get_cpuid_max "cpuid.h" GET_CPUID_MAX_INSTRINSIC_EXISTS)
  check_symbol_exists(__cpuid_count "cpuid.h" GET_CPUID_COUNT_MACRO_INSTRINSIC_EXISTS)
141 142
ELSE()
  check_symbol_exists(__cpuid "intrin.h" GET_CPUID_INSTRINSIC_EXISTS)
steinbac's avatar
steinbac committed
143
ENDIF()
144

steinbac's avatar
steinbac committed
145 146
if(WITH_TESTS)
  add_subdirectory(tests)
steinbac's avatar
steinbac committed
147 148 149 150 151
  enable_testing()
  include("CTestLists.txt")
endif()

################################ EXPORT/INSTALL ################################
steinbac's avatar
steinbac committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
export(
  TARGETS ${COMPASS_TARGET_NAME}
  NAMESPACE ${PROJECT_NAME}::
  FILE ${COMPASS_CMAKE_PROJECT_TARGETS_FILE}
  )
install(
  TARGETS ${COMPASS_TARGET_NAME}
  EXPORT ${PROJECT_NAME}Targets
  INCLUDES DESTINATION ${COMPASS_INCLUDE_INSTALL_DIR}
  )
install(
  EXPORT ${COMPASS_TARGETS_EXPORT_NAME}
  NAMESPACE ${PROJECT_NAME}::
  DESTINATION ${COMPASS_CONFIG_INSTALL_DIR}
  )
steinbac's avatar
steinbac committed
167
install(DIRECTORY "${COMPASS_INCLUDE_BUILD_DIR}"
steinbac's avatar
steinbac committed
168 169 170
  DESTINATION include
  FILES_MATCHING
  PATTERN "*.hpp"
steinbac's avatar
steinbac committed
171
  )