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