xref: /aosp_15_r20/external/cpu_features/CMakeLists.txt (revision eca53ba6d2e951e174b64682eaf56a36b8204c89)
1cmake_minimum_required(VERSION 3.13)
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.9.0 LANGUAGES C)
10
11set(CMAKE_C_STANDARD 99)
12
13# when cpu_features is included as subproject (i.e. using add_subdirectory(cpu_features))
14# in the source tree of a project that uses it, test rules are disabled.
15if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
16  option(BUILD_TESTING "Enable test rule" OFF)
17else()
18  option(BUILD_TESTING "Enable test rule" ON)
19endif()
20
21# Default Build Type to be Release
22if(NOT CMAKE_BUILD_TYPE)
23  set(CMAKE_BUILD_TYPE "Release" CACHE STRING
24      "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
25      FORCE)
26endif(NOT CMAKE_BUILD_TYPE)
27
28# An option to enable/disable the executable target list_cpu_features.
29# Disable it by default if the project is included as a subproject.
30if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
31  option(BUILD_EXECUTABLE "Build list_cpu_features executable." OFF)
32else()
33  option(BUILD_EXECUTABLE "Build list_cpu_features executable." ON)
34endif()
35
36# An option which allows to switch off install steps. Useful for embedding.
37# Disable it by default if the project is included as a subproject.
38if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
39  option(ENABLE_INSTALL "Enable install targets" OFF)
40else()
41  option(ENABLE_INSTALL "Enable install targets" ON)
42endif()
43
44# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
45# it prominent in the GUI.
46# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field).
47# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways.
48# Prefer static linking from source whenever possible.
49option(BUILD_SHARED_LIBS "Build library as shared." OFF)
50
51# Force PIC on unix when building shared libs
52# see: https://en.wikipedia.org/wiki/Position-independent_code
53if(BUILD_SHARED_LIBS AND UNIX)
54  option(CMAKE_POSITION_INDEPENDENT_CODE "Build with Position Independant Code." ON)
55endif()
56
57include(CheckIncludeFile)
58include(CheckSymbolExists)
59include(GNUInstallDirs)
60
61macro(setup_include_and_definitions TARGET_NAME)
62  target_include_directories(${TARGET_NAME}
63    PUBLIC  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
64    PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/internal>
65  )
66  target_compile_definitions(${TARGET_NAME}
67    PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024
68  )
69endmacro()
70
71set(PROCESSOR_IS_MIPS FALSE)
72set(PROCESSOR_IS_ARM FALSE)
73set(PROCESSOR_IS_AARCH64 FALSE)
74set(PROCESSOR_IS_X86 FALSE)
75set(PROCESSOR_IS_POWER FALSE)
76set(PROCESSOR_IS_S390X FALSE)
77set(PROCESSOR_IS_RISCV FALSE)
78set(PROCESSOR_IS_LOONGARCH FALSE)
79
80if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
81  set(PROCESSOR_IS_MIPS TRUE)
82elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)")
83  set(PROCESSOR_IS_AARCH64 TRUE)
84elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
85  set(PROCESSOR_IS_ARM TRUE)
86elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)")
87  set(PROCESSOR_IS_X86 TRUE)
88elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
89  set(PROCESSOR_IS_POWER TRUE)
90elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
91  set(PROCESSOR_IS_S390X TRUE)
92elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
93  set(PROCESSOR_IS_RISCV TRUE)
94elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
95  set(PROCESSOR_IS_LOONGARCH TRUE)
96endif()
97
98macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
99  list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h)
100  list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h)
101  file(GLOB IMPL_SOURCES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/impl_*.c")
102  list(APPEND ${SRCS_LIST_NAME} ${IMPL_SOURCES})
103  if(PROCESSOR_IS_MIPS)
104      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h)
105  elseif(PROCESSOR_IS_ARM)
106      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h)
107  elseif(PROCESSOR_IS_AARCH64)
108      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h)
109      list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
110  elseif(PROCESSOR_IS_X86)
111      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h)
112      list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h)
113      list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
114  elseif(PROCESSOR_IS_POWER)
115      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
116  elseif(PROCESSOR_IS_S390X)
117      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
118  elseif(PROCESSOR_IS_RISCV)
119      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
120  elseif(PROCESSOR_IS_LOONGARCH)
121      list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_loongarch.h)
122  else()
123    message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
124  endif()
125endmacro()
126
127#
128# library : utils
129#
130
131add_library(utils OBJECT
132  ${PROJECT_SOURCE_DIR}/include/internal/bit_utils.h
133  ${PROJECT_SOURCE_DIR}/include/internal/filesystem.h
134  ${PROJECT_SOURCE_DIR}/include/internal/stack_line_reader.h
135  ${PROJECT_SOURCE_DIR}/include/internal/string_view.h
136  ${PROJECT_SOURCE_DIR}/src/filesystem.c
137  ${PROJECT_SOURCE_DIR}/src/stack_line_reader.c
138  ${PROJECT_SOURCE_DIR}/src/string_view.c
139)
140setup_include_and_definitions(utils)
141
142#
143# library : unix_based_hardware_detection
144#
145
146if(UNIX)
147  add_library(unix_based_hardware_detection OBJECT
148    ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h
149    ${PROJECT_SOURCE_DIR}/src/hwcaps.c
150  )
151  setup_include_and_definitions(unix_based_hardware_detection)
152  check_include_file(dlfcn.h HAVE_DLFCN_H)
153  if(HAVE_DLFCN_H)
154    target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H)
155  endif()
156  check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL)
157  if(HAVE_STRONG_GETAUXVAL)
158    target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL)
159  endif()
160endif()
161
162#
163# library : cpu_features
164#
165set (CPU_FEATURES_HDRS)
166set (CPU_FEATURES_SRCS)
167add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS)
168list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:utils>)
169if(NOT PROCESSOR_IS_X86 AND UNIX)
170  list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:unix_based_hardware_detection>)
171endif()
172add_library(cpu_features ${CPU_FEATURES_HDRS} ${CPU_FEATURES_SRCS})
173set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${CPU_FEATURES_HDRS}")
174setup_include_and_definitions(cpu_features)
175target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
176target_include_directories(cpu_features
177  PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
178)
179
180if(APPLE)
181  target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
182endif()
183add_library(CpuFeatures::cpu_features ALIAS cpu_features)
184
185#
186# program : list_cpu_features
187#
188
189if(BUILD_EXECUTABLE)
190  add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c)
191  target_link_libraries(list_cpu_features PRIVATE cpu_features)
192  add_executable(CpuFeatures::list_cpu_features ALIAS list_cpu_features)
193endif()
194
195#
196# ndk_compat
197#
198
199if(ANDROID)
200add_subdirectory(ndk_compat)
201endif()
202
203#
204# tests
205#
206
207include(CTest)
208if(BUILD_TESTING)
209  # Automatically incorporate googletest into the CMake Project if target not
210  # found.
211  enable_language(CXX)
212
213  set(CMAKE_CXX_STANDARD 14)
214  set(CMAKE_CXX_STANDARD_REQUIRED ON)
215  set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std14 instead of -gnustd14
216
217  if(NOT TARGET gtest OR NOT TARGET gmock_main)
218    # Download and unpack googletest at configure time.
219    configure_file(
220      cmake/googletest.CMakeLists.txt.in
221      googletest-download/CMakeLists.txt
222    )
223
224    execute_process(
225      COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
226      RESULT_VARIABLE result
227      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
228
229    if(result)
230      message(FATAL_ERROR "CMake step for googletest failed: ${result}")
231    endif()
232
233    execute_process(
234      COMMAND ${CMAKE_COMMAND} --build .
235      RESULT_VARIABLE result
236      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
237
238    if(result)
239      message(FATAL_ERROR "Build step for googletest failed: ${result}")
240    endif()
241
242    # Prevent overriding the parent project's compiler/linker settings on
243    # Windows.
244    set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
245
246    # Add googletest directly to our build. This defines the gtest and
247    # gtest_main targets.
248    add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
249                     ${CMAKE_BINARY_DIR}/googletest-build
250                     EXCLUDE_FROM_ALL)
251  endif()
252
253  add_subdirectory(test)
254endif()
255
256#
257# Install cpu_features and list_cpu_features
258#
259if(ENABLE_INSTALL)
260  include(GNUInstallDirs)
261  install(TARGETS cpu_features
262    EXPORT CpuFeaturesTargets
263    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
264    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
265    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
266    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
267    BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
268  )
269  if(BUILD_EXECUTABLE)
270    install(TARGETS list_cpu_features
271      EXPORT CpuFeaturesTargets
272      PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
273      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
274      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
275      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
276      BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
277    )
278  endif()
279  install(EXPORT CpuFeaturesTargets
280    NAMESPACE CpuFeatures::
281    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures
282    COMPONENT Devel
283  )
284  include(CMakePackageConfigHelpers)
285  configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in
286    "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake"
287    INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures"
288    NO_SET_AND_CHECK_MACRO
289    NO_CHECK_REQUIRED_COMPONENTS_MACRO
290  )
291  write_basic_package_version_file(
292    "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
293    COMPATIBILITY SameMajorVersion
294  )
295  install(
296    FILES
297      "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake"
298      "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
299    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures"
300    COMPONENT Devel
301  )
302endif()
303