1cmake_minimum_required(VERSION 3.0) 2 3# option() honors normal variables. 4# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html 5if(POLICY CMP0077) 6 cmake_policy(SET CMP0077 NEW) 7endif() 8 9project(CpuFeatures VERSION 0.6.0 LANGUAGES C) 10 11set(CMAKE_C_STANDARD 99) 12 13# Default Build Type to be Release 14if(NOT CMAKE_BUILD_TYPE) 15 set(CMAKE_BUILD_TYPE "Release" CACHE STRING 16 "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." 17 FORCE) 18endif(NOT CMAKE_BUILD_TYPE) 19 20# BUILD_TESTING is a standard CMake variable, but we declare it here to make it 21# prominent in the GUI. 22option(BUILD_TESTING "Enable test (depends on googletest)." OFF) 23# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make 24# it prominent in the GUI. 25# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). 26# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways. 27# Prefer static linking from source whenever possible. 28option(BUILD_SHARED_LIBS "Build library as shared." OFF) 29# PIC 30option(BUILD_PIC "Build with Position Independant Code." OFF) # Default is off at least for GCC 31 32# Force PIC on unix when building shared libs 33# see: https://en.wikipedia.org/wiki/Position-independent_code 34if(BUILD_SHARED_LIBS AND UNIX) 35 set(BUILD_PIC ON) 36endif() 37 38include(CheckIncludeFile) 39include(CheckSymbolExists) 40include(GNUInstallDirs) 41 42macro(setup_include_and_definitions TARGET_NAME) 43 target_include_directories(${TARGET_NAME} 44 PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> 45 PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/internal> 46 ) 47 target_compile_definitions(${TARGET_NAME} 48 PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024 49 ) 50endmacro() 51 52set(PROCESSOR_IS_MIPS FALSE) 53set(PROCESSOR_IS_ARM FALSE) 54set(PROCESSOR_IS_AARCH64 FALSE) 55set(PROCESSOR_IS_X86 FALSE) 56set(PROCESSOR_IS_POWER FALSE) 57 58if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") 59 set(PROCESSOR_IS_MIPS TRUE) 60elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") 61 set(PROCESSOR_IS_ARM TRUE) 62elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") 63 set(PROCESSOR_IS_AARCH64 TRUE) 64elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") 65 set(PROCESSOR_IS_X86 TRUE) 66elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") 67 set(PROCESSOR_IS_POWER TRUE) 68endif() 69 70macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) 71 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) 72 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h) 73 if(PROCESSOR_IS_MIPS) 74 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) 75 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c) 76 elseif(PROCESSOR_IS_ARM) 77 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) 78 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c) 79 elseif(PROCESSOR_IS_AARCH64) 80 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) 81 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c) 82 elseif(PROCESSOR_IS_X86) 83 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) 84 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) 85 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c) 86 elseif(PROCESSOR_IS_POWER) 87 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) 88 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c) 89 else() 90 message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") 91 endif() 92endmacro() 93 94# 95# library : utils 96# 97 98add_library(utils OBJECT 99 ${PROJECT_SOURCE_DIR}/include/internal/bit_utils.h 100 ${PROJECT_SOURCE_DIR}/include/internal/filesystem.h 101 ${PROJECT_SOURCE_DIR}/include/internal/stack_line_reader.h 102 ${PROJECT_SOURCE_DIR}/include/internal/string_view.h 103 ${PROJECT_SOURCE_DIR}/src/filesystem.c 104 ${PROJECT_SOURCE_DIR}/src/stack_line_reader.c 105 ${PROJECT_SOURCE_DIR}/src/string_view.c 106) 107set_property(TARGET utils PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) 108setup_include_and_definitions(utils) 109 110# 111# library : unix_based_hardware_detection 112# 113 114if(UNIX) 115 add_library(unix_based_hardware_detection OBJECT 116 ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h 117 ${PROJECT_SOURCE_DIR}/src/hwcaps.c 118 ) 119 setup_include_and_definitions(unix_based_hardware_detection) 120 check_include_file(dlfcn.h HAVE_DLFCN_H) 121 if(HAVE_DLFCN_H) 122 target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H) 123 endif() 124 check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL) 125 if(HAVE_STRONG_GETAUXVAL) 126 target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL) 127 endif() 128 set_property(TARGET unix_based_hardware_detection PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) 129endif() 130 131# 132# library : cpu_features 133# 134set (CPU_FEATURES_HDRS) 135set (CPU_FEATURES_SRCS) 136add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS) 137list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:utils>) 138if(NOT PROCESSOR_IS_X86 AND UNIX) 139 list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:unix_based_hardware_detection>) 140endif() 141add_library(cpu_features ${CPU_FEATURES_HDRS} ${CPU_FEATURES_SRCS}) 142set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${CPU_FEATURES_HDRS}") 143setup_include_and_definitions(cpu_features) 144target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) 145set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) 146target_include_directories(cpu_features 147 PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features> 148) 149if(PROCESSOR_IS_X86) 150 if(APPLE) 151 target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) 152 endif() 153endif() 154add_library(CpuFeature::cpu_features ALIAS cpu_features) 155 156# 157# program : list_cpu_features 158# 159 160add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c) 161target_link_libraries(list_cpu_features PRIVATE cpu_features) 162add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features) 163 164# 165# ndk_compat 166# 167 168if(ANDROID) 169add_subdirectory(ndk_compat) 170endif() 171 172# 173# tests 174# 175 176include(CTest) 177if(BUILD_TESTING) 178 # Automatically incorporate googletest into the CMake Project if target not 179 # found. 180 enable_language(CXX) 181 182 set(CMAKE_CXX_STANDARD 11) 183 set(CMAKE_CXX_STANDARD_REQUIRED ON) 184 set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std11 instead of -gnustd11 185 186 if(NOT TARGET gtest OR NOT TARGET gmock_main) 187 # Download and unpack googletest at configure time. 188 configure_file( 189 cmake/googletest.CMakeLists.txt.in 190 googletest-download/CMakeLists.txt 191 ) 192 193 execute_process( 194 COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . 195 RESULT_VARIABLE result 196 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) 197 198 if(result) 199 message(FATAL_ERROR "CMake step for googletest failed: ${result}") 200 endif() 201 202 execute_process( 203 COMMAND ${CMAKE_COMMAND} --build . 204 RESULT_VARIABLE result 205 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) 206 207 if(result) 208 message(FATAL_ERROR "Build step for googletest failed: ${result}") 209 endif() 210 211 # Prevent overriding the parent project's compiler/linker settings on 212 # Windows. 213 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 214 215 # Add googletest directly to our build. This defines the gtest and 216 # gtest_main targets. 217 add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src 218 ${CMAKE_BINARY_DIR}/googletest-build 219 EXCLUDE_FROM_ALL) 220 endif() 221 222 add_subdirectory(test) 223endif() 224 225# 226# Install cpu_features and list_cpu_features 227# 228 229include(GNUInstallDirs) 230install(TARGETS cpu_features list_cpu_features 231 EXPORT CpuFeaturesTargets 232 PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features 233 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 234 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 235 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 236) 237install(EXPORT CpuFeaturesTargets 238 NAMESPACE CpuFeatures:: 239 DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures 240 COMPONENT Devel 241) 242include(CMakePackageConfigHelpers) 243configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in 244 "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" 245 INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" 246 NO_SET_AND_CHECK_MACRO 247 NO_CHECK_REQUIRED_COMPONENTS_MACRO 248) 249write_basic_package_version_file( 250 "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" 251 COMPATIBILITY SameMajorVersion 252) 253install( 254 FILES 255 "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" 256 "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" 257 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" 258 COMPONENT Devel 259) 260