• 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.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