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)
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)

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

74
if (NOT WITH_SINGLE_HEADER)
steinbac's avatar
steinbac committed
75
    set(COMPASS_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include")
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")
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
  )
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()

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()
126

127
  if(${WITH_CXX11_ABI})
128
    set(CXX11_ABI_VALUE 1)
129
  else()
130
    set(CXX11_ABI_VALUE 0)
131
  endif()
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()
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)
143
ENDIF()
144

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 ################################
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"
171
  )