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