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