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.7.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) 52 53if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") 54 set(PROCESSOR_IS_MIPS TRUE) 55elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") 56 set(PROCESSOR_IS_AARCH64 TRUE) 57elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") 58 set(PROCESSOR_IS_ARM TRUE) 59elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") 60 set(PROCESSOR_IS_X86 TRUE) 61elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") 62 set(PROCESSOR_IS_POWER TRUE) 63endif() 64 65macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) 66 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) 67 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h) 68 file(GLOB IMPL_SOURCES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/impl_*.c") 69 list(APPEND ${SRCS_LIST_NAME} ${IMPL_SOURCES}) 70 if(PROCESSOR_IS_MIPS) 71 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) 72 elseif(PROCESSOR_IS_ARM) 73 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) 74 elseif(PROCESSOR_IS_AARCH64) 75 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) 76 elseif(PROCESSOR_IS_X86) 77 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) 78 list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) 79 elseif(PROCESSOR_IS_POWER) 80 list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) 81 else() 82 message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") 83 endif() 84endmacro() 85 86# 87# library : utils 88# 89 90add_library(utils OBJECT 91 ${PROJECT_SOURCE_DIR}/include/internal/bit_utils.h 92 ${PROJECT_SOURCE_DIR}/include/internal/filesystem.h 93 ${PROJECT_SOURCE_DIR}/include/internal/stack_line_reader.h 94 ${PROJECT_SOURCE_DIR}/include/internal/string_view.h 95 ${PROJECT_SOURCE_DIR}/src/filesystem.c 96 ${PROJECT_SOURCE_DIR}/src/stack_line_reader.c 97 ${PROJECT_SOURCE_DIR}/src/string_view.c 98) 99setup_include_and_definitions(utils) 100 101# 102# library : unix_based_hardware_detection 103# 104 105if(UNIX) 106 add_library(unix_based_hardware_detection OBJECT 107 ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h 108 ${PROJECT_SOURCE_DIR}/src/hwcaps.c 109 ) 110 setup_include_and_definitions(unix_based_hardware_detection) 111 check_include_file(dlfcn.h HAVE_DLFCN_H) 112 if(HAVE_DLFCN_H) 113 target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H) 114 endif() 115 check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL) 116 if(HAVE_STRONG_GETAUXVAL) 117 target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL) 118 endif() 119endif() 120 121# 122# library : cpu_features 123# 124set (CPU_FEATURES_HDRS) 125set (CPU_FEATURES_SRCS) 126add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS) 127list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:utils>) 128if(NOT PROCESSOR_IS_X86 AND UNIX) 129 list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:unix_based_hardware_detection>) 130endif() 131add_library(cpu_features ${CPU_FEATURES_HDRS} ${CPU_FEATURES_SRCS}) 132set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${CPU_FEATURES_HDRS}") 133setup_include_and_definitions(cpu_features) 134target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) 135target_include_directories(cpu_features 136 PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features> 137) 138if(PROCESSOR_IS_X86) 139 if(APPLE) 140 target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) 141 endif() 142endif() 143add_library(CpuFeature::cpu_features ALIAS cpu_features) 144 145# 146# program : list_cpu_features 147# 148 149add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c) 150target_link_libraries(list_cpu_features PRIVATE cpu_features) 151add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features) 152 153# 154# ndk_compat 155# 156 157if(ANDROID) 158add_subdirectory(ndk_compat) 159endif() 160 161# 162# tests 163# 164 165include(CTest) 166if(BUILD_TESTING) 167 # Automatically incorporate googletest into the CMake Project if target not 168 # found. 169 enable_language(CXX) 170 171 set(CMAKE_CXX_STANDARD 11) 172 set(CMAKE_CXX_STANDARD_REQUIRED ON) 173 set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std11 instead of -gnustd11 174 175 if(NOT TARGET gtest OR NOT TARGET gmock_main) 176 # Download and unpack googletest at configure time. 177 configure_file( 178 cmake/googletest.CMakeLists.txt.in 179 googletest-download/CMakeLists.txt 180 ) 181 182 execute_process( 183 COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . 184 RESULT_VARIABLE result 185 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) 186 187 if(result) 188 message(FATAL_ERROR "CMake step for googletest failed: ${result}") 189 endif() 190 191 execute_process( 192 COMMAND ${CMAKE_COMMAND} --build . 193 RESULT_VARIABLE result 194 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) 195 196 if(result) 197 message(FATAL_ERROR "Build step for googletest failed: ${result}") 198 endif() 199 200 # Prevent overriding the parent project's compiler/linker settings on 201 # Windows. 202 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 203 204 # Add googletest directly to our build. This defines the gtest and 205 # gtest_main targets. 206 add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src 207 ${CMAKE_BINARY_DIR}/googletest-build 208 EXCLUDE_FROM_ALL) 209 endif() 210 211 add_subdirectory(test) 212endif() 213 214# 215# Install cpu_features and list_cpu_features 216# 217 218include(GNUInstallDirs) 219install(TARGETS cpu_features list_cpu_features 220 EXPORT CpuFeaturesTargets 221 PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features 222 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 223 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 224 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 225 BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} 226) 227install(EXPORT CpuFeaturesTargets 228 NAMESPACE CpuFeatures:: 229 DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures 230 COMPONENT Devel 231) 232include(CMakePackageConfigHelpers) 233configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in 234 "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" 235 INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" 236 NO_SET_AND_CHECK_MACRO 237 NO_CHECK_REQUIRED_COMPONENTS_MACRO 238) 239write_basic_package_version_file( 240 "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" 241 COMPATIBILITY SameMajorVersion 242) 243install( 244 FILES 245 "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" 246 "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" 247 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" 248 COMPONENT Devel 249) 250