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