• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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