CMakeLists.txt (31590B)
1 # Copyright 2019 Google LLC 2 # Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> 3 # SPDX-License-Identifier: Apache-2.0 4 # SPDX-License-Identifier: BSD-3-Clause 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 18 cmake_minimum_required(VERSION 3.10) 19 20 # Set PIE flags for POSITION_INDEPENDENT_CODE targets, added in 3.14. 21 if(POLICY CMP0083) 22 cmake_policy(SET CMP0083 NEW) 23 endif() 24 25 # Workaround for 3.19 raising error 'IMPORTED_LOCATION not set for imported 26 # target "GTest::gtest_main"'. 27 if(POLICY CMP0111) 28 cmake_policy(SET CMP0111 OLD) 29 endif() 30 31 # Starting with GCC-13, we want to make sure to remove gnu extension (ie. 32 # explicit -std=c++17 instead of implicit `gnu++17`) 33 # Without this cmake property, CMAKE_CXX_EXTENSIONS=OFF was not properly 34 # considered 35 if(POLICY CMP0128) 36 cmake_policy(SET CMP0128 NEW) 37 endif() 38 39 project(hwy VERSION 1.3.0) # Keep in sync with base.h version 40 # `hwy` is lowercase to handle find_package() in Config mode: 41 set(namespace "${PROJECT_NAME}::") 42 43 # Directly define the ABI version from the cmake project() version values: 44 set(LIBRARY_VERSION "${hwy_VERSION}") 45 set(LIBRARY_SOVERSION ${hwy_VERSION_MAJOR}) 46 47 set(CMAKE_CXX_EXTENSIONS OFF) 48 49 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 50 # Search for Atomics implementation: 51 find_package(Atomics REQUIRED) 52 53 # Enabled PIE binaries by default if supported. 54 include(CheckPIESupported OPTIONAL RESULT_VARIABLE CHECK_PIE_SUPPORTED) 55 if(CHECK_PIE_SUPPORTED) 56 check_pie_supported(LANGUAGES CXX) 57 if(CMAKE_CXX_LINK_PIE_SUPPORTED) 58 set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) 59 endif() 60 endif() 61 62 include(GNUInstallDirs) 63 64 if (NOT CMAKE_BUILD_TYPE) 65 set(CMAKE_BUILD_TYPE RelWithDebInfo) 66 endif() 67 68 # The following is only required with GCC < 6.1.0 or CLANG < 16.0 69 set(HWY_CMAKE_ARM7 OFF CACHE BOOL "Set copts for Armv7 with NEON (requires vfpv4)?") 70 71 # This must be set on 32-bit x86 with GCC < 13.1, otherwise math_test will be 72 # skipped. For GCC 13.1+, you can also build with -fexcess-precision=standard. 73 set(HWY_CMAKE_SSE2 OFF CACHE BOOL "Set SSE2 as baseline for 32-bit x86?") 74 75 # Currently this will compile the entire codebase with `-march=rv<XLEN>gcv1p0`: 76 set(HWY_CMAKE_RVV ON CACHE BOOL "Set copts for RISCV with RVV?") 77 78 # Unconditionally adding -Werror risks breaking the build when new warnings 79 # arise due to compiler/platform changes. Enable this in CI/tests. 80 set(HWY_WARNINGS_ARE_ERRORS OFF CACHE BOOL "Add -Werror flag?") 81 82 # Experimental support for header-only builds 83 set(HWY_CMAKE_HEADER_ONLY OFF CACHE BOOL "Change to header-only?") 84 85 set(HWY_ENABLE_CONTRIB ON CACHE BOOL "Include contrib/") 86 set(HWY_ENABLE_EXAMPLES ON CACHE BOOL "Build examples") 87 set(HWY_ENABLE_INSTALL ON CACHE BOOL "Install library") 88 set(HWY_ENABLE_TESTS ON CACHE BOOL "Enable HWY tests") 89 90 if (MSVC) 91 set(HWY_TEST_STANDALONE ON CACHE BOOL "Disable use of googletest") 92 else() 93 set(HWY_TEST_STANDALONE OFF CACHE BOOL "Disable use of googletest") 94 endif() 95 96 if (NOT DEFINED CMAKE_CXX_STANDARD) 97 if ("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 98 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_17) 99 else() 100 if ("cxx_std_14" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 101 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_14) 102 else() 103 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_11) 104 endif() 105 endif() 106 else() 107 if (CMAKE_CXX_STANDARD GREATER_EQUAL 14 AND CMAKE_CXX_STANDARD LESS 98) 108 if (CMAKE_CXX_STANDARD GREATER_EQUAL 17) 109 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_17) 110 else() 111 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_14) 112 endif() 113 else() 114 set(HWY_CXX_STD_TGT_COMPILE_FEATURE cxx_std_11) 115 endif() 116 endif() 117 118 include(CheckCXXSourceCompiles) 119 check_cxx_source_compiles( 120 "int main() { 121 #if !defined(__EMSCRIPTEN__) 122 static_assert(false, \"__EMSCRIPTEN__ is not defined\"); 123 #endif 124 return 0; 125 }" 126 HWY_EMSCRIPTEN 127 ) 128 129 check_cxx_source_compiles( 130 "int main() { 131 #if !defined(__riscv) 132 static_assert(false, \"__riscv is not defined\"); 133 #endif 134 return 0; 135 }" 136 HWY_RISCV 137 ) 138 139 if (WIN32) 140 set (ORIG_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) 141 set (CMAKE_REQUIRED_LIBRARIES synchronization) 142 check_cxx_source_compiles( 143 "#ifndef NOMINMAX 144 #define NOMINMAX 145 #endif 146 147 #include <windows.h> 148 149 int main() { 150 unsigned val1 = 0u; 151 unsigned val2 = 1u; 152 WaitOnAddress(&val1, &val2, sizeof(unsigned), 1); 153 WakeByAddressAll(&val1); 154 WakeByAddressSingle(&val1); 155 return 0; 156 }" 157 HWY_HAVE_WIN32_SYNCHRONIZATION_LIB) 158 set (CMAKE_REQUIRED_LIBRARIES ${ORIG_CMAKE_REQUIRED_LIBRARIES}) 159 else() 160 set (HWY_HAVE_WIN32_SYNCHRONIZATION_LIB OFF) 161 endif () 162 163 if (HWY_HAVE_WIN32_SYNCHRONIZATION_LIB OR NOT WIN32) 164 set (HWY_DISABLE_FUTEX OFF CACHE BOOL "Disable futex for thread_pool") 165 else() 166 # Force HWY_DISABLE_FUTEX to ON if compiling for Win32 and 167 # libsynchronization.a or synchronization.lib is not available 168 set (HWY_DISABLE_FUTEX ON CACHE BOOL "Disable futex for thread_pool" FORCE) 169 endif() 170 171 find_package(Threads) 172 173 if (NOT Threads_FOUND AND HWY_ENABLE_CONTRIB) 174 message(FATAL_ERROR "Threads must be available if HWY_ENABLE_CONTRIB is ON") 175 endif() 176 177 if(Threads_FOUND) 178 if(THREADS_HAVE_PTHREAD_ARG) 179 set(HWY_THREAD_FLAGS "-pthread") 180 else() 181 set(HWY_THREAD_FLAGS "") 182 endif() 183 184 if(CMAKE_THREAD_LIBS_INIT) 185 set(HWY_THREAD_LIBS ${CMAKE_THREAD_LIBS_INIT}) 186 else() 187 set(HWY_THREAD_LIBS "") 188 endif() 189 else() 190 set(HWY_THREAD_FLAGS "") 191 set(HWY_THREAD_LIBS "") 192 endif() 193 194 if (HWY_RISCV OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "RISCV32|RISCV64|RISCV128" OR CMAKE_SYSTEM_PROCESSOR MATCHES "riscv32|riscv64|riscv128") 195 include(CheckCSourceCompiles) 196 check_c_source_compiles(" 197 #if __riscv_xlen == 64 198 int main() { return 0; } 199 #else 200 #error Not RISCV-64 201 #endif 202 " IS_RISCV_XLEN_64) 203 204 check_c_source_compiles(" 205 #if __riscv_xlen == 32 206 int main() { return 0; } 207 #else 208 #error Not RISCV-32 209 #endif 210 " IS_RISCV_XLEN_32) 211 212 if(IS_RISCV_XLEN_32) 213 set(RISCV_XLEN 32) 214 elseif(IS_RISCV_XLEN_64) 215 set(RISCV_XLEN 64) 216 else() 217 message(WARNING "Unable to determine RISC-V XLEN") 218 endif() 219 endif() 220 221 if (HWY_ENABLE_CONTRIB) 222 # Glob all the traits so we don't need to modify this file when adding 223 # additional special cases. 224 file(GLOB HWY_CONTRIB_SOURCES "hwy/contrib/sort/vqsort_*.cc") 225 list(APPEND HWY_CONTRIB_SOURCES 226 hwy/contrib/bit_pack/bit_pack-inl.h 227 hwy/contrib/dot/dot-inl.h 228 hwy/contrib/image/image.cc 229 hwy/contrib/image/image.h 230 hwy/contrib/math/math-inl.h 231 hwy/contrib/matvec/matvec-inl.h 232 hwy/contrib/random/random-inl.h 233 hwy/contrib/sort/order.h 234 hwy/contrib/sort/shared-inl.h 235 hwy/contrib/sort/sorting_networks-inl.h 236 hwy/contrib/sort/traits-inl.h 237 hwy/contrib/sort/traits128-inl.h 238 hwy/contrib/sort/vqsort-inl.h 239 hwy/contrib/sort/vqsort.cc 240 hwy/contrib/sort/vqsort.h 241 hwy/contrib/thread_pool/futex.h 242 hwy/contrib/thread_pool/spin.h 243 hwy/contrib/thread_pool/thread_pool.cc 244 hwy/contrib/thread_pool/thread_pool.h 245 hwy/contrib/thread_pool/topology.cc 246 hwy/contrib/thread_pool/topology.h 247 hwy/contrib/algo/copy-inl.h 248 hwy/contrib/algo/find-inl.h 249 hwy/contrib/algo/transform-inl.h 250 hwy/contrib/unroller/unroller-inl.h 251 ) 252 endif() # HWY_ENABLE_CONTRIB 253 254 set(HWY_SOURCES 255 hwy/abort.h 256 hwy/aligned_allocator.h 257 hwy/auto_tune.h 258 hwy/base.h 259 hwy/cache_control.h 260 hwy/detect_compiler_arch.h # private 261 hwy/detect_targets.h # private 262 hwy/foreach_target.h 263 hwy/highway_export.h 264 hwy/highway.h 265 hwy/nanobenchmark.h 266 hwy/ops/arm_neon-inl.h 267 hwy/ops/arm_sve-inl.h 268 hwy/ops/emu128-inl.h 269 hwy/ops/generic_ops-inl.h 270 hwy/ops/inside-inl.h 271 hwy/ops/loongarch_lsx-inl.h 272 hwy/ops/loongarch_lasx-inl.h 273 hwy/ops/ppc_vsx-inl.h 274 hwy/ops/rvv-inl.h 275 hwy/ops/scalar-inl.h 276 hwy/ops/set_macros-inl.h 277 hwy/ops/shared-inl.h 278 hwy/ops/wasm_128-inl.h 279 hwy/ops/x86_128-inl.h 280 hwy/ops/x86_256-inl.h 281 hwy/ops/x86_512-inl.h 282 hwy/ops/x86_avx3-inl.h 283 hwy/per_target.h 284 hwy/print-inl.h 285 hwy/print.h 286 hwy/profiler.h 287 hwy/robust_statistics.h 288 hwy/targets.h 289 hwy/timer-inl.h 290 hwy/timer.h 291 hwy/x86_cpuid.h 292 ) 293 294 if (NOT HWY_CMAKE_HEADER_ONLY) 295 list(APPEND HWY_SOURCES 296 hwy/abort.cc 297 hwy/aligned_allocator.cc 298 hwy/nanobenchmark.cc 299 hwy/per_target.cc 300 hwy/perf_counters.cc 301 hwy/print.cc 302 hwy/profiler.cc 303 hwy/targets.cc 304 hwy/timer.cc 305 ) 306 endif() 307 308 set(HWY_TEST_SOURCES 309 hwy/tests/hwy_gtest.h 310 hwy/tests/test_util-inl.h 311 hwy/tests/test_util.cc 312 hwy/tests/test_util.h 313 ) 314 315 if (MSVC) 316 set(HWY_FLAGS 317 # fix build error C1128 in blockwise*_test & arithmetic_test 318 /bigobj 319 320 # Warnings 321 /W4 322 # Disable some W4 warnings. Enable them individually after they are cleaned up. 323 /wd4100 324 /wd4127 325 /wd4324 326 /wd4456 327 /wd4701 328 /wd4702 329 /wd4723 330 331 # CMake automatically adds exception handling flags. Remove them. 332 /GR- 333 /EHs-c- 334 # Disable exceptions in STL code. 335 -D_HAS_EXCEPTIONS=0 336 ) 337 338 # This adds extra warnings for the clang-cl compiler on Windows. 339 # This is the same as the sections in the else part. 340 # These could be refactored. 341 if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 342 list(APPEND HWY_FLAGS 343 # These are not included in Wall nor Wextra: 344 -Wconversion 345 -Wsign-conversion 346 -Wvla 347 -Wnon-virtual-dtor 348 349 -Wfloat-overflow-conversion 350 -Wfloat-zero-conversion 351 -Wfor-loop-analysis 352 -Wgnu-redeclared-enum 353 -Winfinite-recursion 354 -Wself-assign 355 -Wstring-conversion 356 -Wtautological-overlap-compare 357 -Wthread-safety-analysis 358 -Wundefined-func-template 359 ) 360 endif() 361 362 if (HWY_WARNINGS_ARE_ERRORS) 363 list(APPEND HWY_FLAGS /WX) 364 endif() 365 else() 366 set(HWY_FLAGS 367 # Avoid changing binaries based on the current time and date. 368 -Wno-builtin-macro-redefined 369 -D__DATE__="redacted" 370 -D__TIMESTAMP__="redacted" 371 -D__TIME__="redacted" 372 373 # Optimizations 374 -fmerge-all-constants 375 376 # Warnings 377 -Wall 378 -Wextra 379 # These are not included in Wall nor Wextra: 380 -Wconversion 381 -Wsign-conversion 382 -Wvla 383 -Wnon-virtual-dtor 384 -Wcast-align # see -Wcast-align=strict on x86 385 ) 386 387 if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 388 list(APPEND HWY_FLAGS 389 -Wfloat-overflow-conversion 390 -Wfloat-zero-conversion 391 -Wfor-loop-analysis 392 -Wgnu-redeclared-enum 393 -Winfinite-recursion 394 -Wself-assign 395 -Wstring-conversion 396 -Wtautological-overlap-compare 397 -Wthread-safety-analysis 398 -Wundefined-func-template 399 400 -fno-cxx-exceptions 401 -fno-slp-vectorize 402 -fno-vectorize 403 404 # Use color in messages 405 -fdiagnostics-show-option -fcolor-diagnostics 406 ) 407 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) 408 list(APPEND HWY_FLAGS -Wc++2a-extensions) 409 endif() 410 endif() 411 412 if (WIN32) 413 if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 414 list(APPEND HWY_FLAGS 415 -Wno-global-constructors 416 -Wno-language-extension-token 417 -Wno-used-but-marked-unused 418 -Wno-shadow-field-in-constructor 419 -Wno-unused-member-function 420 -Wno-unused-template 421 -Wno-c++98-compat-pedantic 422 -Wno-used-but-marked-unused 423 -Wno-zero-as-null-pointer-constant 424 ) 425 endif() 426 427 list(APPEND HWY_FLAGS 428 -Wno-cast-align 429 -Wno-double-promotion 430 -Wno-float-equal 431 -Wno-format-nonliteral 432 -Wno-shadow 433 -Wno-sign-conversion 434 ) 435 else() 436 list(APPEND HWY_FLAGS 437 -fmath-errno 438 -fno-exceptions 439 ) 440 endif() # WIN32 441 442 # Workaround for excess precision, see #1488. 443 if (HWY_CMAKE_SSE2) 444 list(APPEND HWY_FLAGS -msse2 -mfpmath=sse) 445 endif() 446 447 # Suppress STL iterator warnings. Supported by GCC 4.4.7 and newer, which 448 # predates the C++11 we require. 449 if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") 450 list(APPEND HWY_FLAGS -Wno-psabi) 451 endif() 452 # Clang supports this flag from 11.0. 453 if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 454 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) 455 list(APPEND HWY_FLAGS -Wno-psabi) 456 endif() 457 endif() 458 459 if (HWY_CMAKE_ARM7) 460 list(APPEND HWY_FLAGS 461 -march=armv7-a 462 -mfpu=neon-vfpv4 463 -mfloat-abi=hard # must match the toolchain specified as CXX= 464 -DHWY_HAVE_SCALAR_F16_TYPE=0 # See #2625 465 -DHWY_NEON_HAVE_F16C=0 466 ) 467 if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") 468 # using GCC 469 list(APPEND HWY_FLAGS 470 -mfp16-format=ieee # required for vcvt_f32_f16 471 ) 472 endif() 473 endif() # HWY_CMAKE_ARM7 474 475 if(HWY_RISCV) 476 # gcc(13) and recent clang both support V, but not yet runtime dispatch, so 477 # we add the gcv compiler flag, which then requires the CPU (now when using 478 # either compiler) to support V. 479 if(HWY_CMAKE_RVV) 480 if(RISCV_XLEN EQUAL 64) 481 list(APPEND HWY_FLAGS -march=rv64gcv1p0) 482 add_link_options(-march=rv64gcv1p0) 483 elseif(RISCV_XLEN EQUAL 32) 484 list(APPEND HWY_FLAGS -march=rv32gcv1p0) 485 add_link_options(-march=rv32gcv1p0) 486 endif() 487 if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 488 list(APPEND HWY_FLAGS -menable-experimental-extensions) 489 endif() 490 endif() 491 endif() 492 493 if (HWY_WARNINGS_ARE_ERRORS) 494 list(APPEND HWY_FLAGS -Werror) 495 endif() 496 497 # Prevent "wasm-ld: error: --shared-memory is disallowed by targets.cc.o 498 # because it was not compiled with 'atomics' or 'bulk-memory' features." 499 if (HWY_EMSCRIPTEN) 500 list(APPEND HWY_FLAGS -matomics) 501 endif() 502 503 endif() # !MSVC 504 505 if (HWY_DISABLE_FUTEX) 506 list(APPEND HWY_FLAGS -DHWY_DISABLE_FUTEX) 507 endif() 508 509 if (HWY_CMAKE_HEADER_ONLY) 510 list(APPEND HWY_FLAGS -DHWY_HEADER_ONLY) 511 endif() 512 513 include(CheckIncludeFile) 514 check_include_file(sys/auxv.h HAVE_SYS_AUXV_H) 515 check_include_file(asm/hwcap.h HAVE_ASM_HWCAP_H) 516 517 # By default prefer STATIC build (legacy behavior) 518 option(BUILD_SHARED_LIBS "Build shared libraries" OFF) 519 option(HWY_FORCE_STATIC_LIBS "Ignore BUILD_SHARED_LIBS" OFF) 520 # only expose shared/static options to advanced users: 521 mark_as_advanced(BUILD_SHARED_LIBS) 522 mark_as_advanced(HWY_FORCE_STATIC_LIBS) 523 # Define visibility settings globally: 524 set(CMAKE_CXX_VISIBILITY_PRESET hidden) 525 set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) 526 527 # Copy-cat "add_library" logic + add override. 528 set(HWY_LIBRARY_TYPE "SHARED") 529 if (NOT BUILD_SHARED_LIBS OR HWY_FORCE_STATIC_LIBS) 530 set(HWY_LIBRARY_TYPE "STATIC") 531 endif() 532 533 # This preprocessor define will drive the build, also used in the *.pc files: 534 if("${HWY_LIBRARY_TYPE}" STREQUAL "SHARED") 535 set(DLLEXPORT_TO_DEFINE "HWY_SHARED_DEFINE") 536 else() 537 set(DLLEXPORT_TO_DEFINE "HWY_STATIC_DEFINE") 538 endif() 539 540 add_library(hwy ${HWY_LIBRARY_TYPE} ${HWY_SOURCES}) 541 if(NOT HAVE_SYS_AUXV_H) 542 target_compile_definitions(hwy PUBLIC TOOLCHAIN_MISS_SYS_AUXV_H) 543 endif() 544 if(NOT HAVE_ASM_HWCAP_H) 545 target_compile_definitions(hwy PUBLIC TOOLCHAIN_MISS_ASM_HWCAP_H) 546 endif() 547 target_compile_definitions(hwy PUBLIC "${DLLEXPORT_TO_DEFINE}") 548 target_compile_options(hwy PRIVATE ${HWY_FLAGS}) 549 set_property(TARGET hwy PROPERTY POSITION_INDEPENDENT_CODE ON) 550 set_target_properties(hwy PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION}) 551 target_include_directories(hwy PUBLIC 552 $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> 553 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 554 target_compile_features(hwy PUBLIC cxx_std_11) 555 if (NOT HWY_CXX_STD_TGT_COMPILE_FEATURE STREQUAL "cxx_std_11") 556 target_compile_features(hwy PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 557 endif() 558 set_target_properties(hwy PROPERTIES 559 LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version) 560 # For GCC __atomic_store_8, see #887 561 target_link_libraries(hwy PRIVATE ${ATOMICS_LIBRARIES}) 562 # not supported by MSVC/Clang, safe to skip (we use DLLEXPORT annotations) 563 if(UNIX AND NOT APPLE) 564 set_property(TARGET hwy APPEND_STRING PROPERTY 565 LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version") 566 endif() 567 568 if (HWY_ENABLE_CONTRIB) 569 add_library(hwy_contrib ${HWY_LIBRARY_TYPE} ${HWY_CONTRIB_SOURCES}) 570 target_link_libraries(hwy_contrib PUBLIC hwy) 571 target_compile_options(hwy_contrib PRIVATE ${HWY_FLAGS} ${HWY_THREAD_FLAGS}) 572 set_property(TARGET hwy_contrib PROPERTY POSITION_INDEPENDENT_CODE ON) 573 set_target_properties(hwy_contrib PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION}) 574 target_include_directories(hwy_contrib PUBLIC 575 $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> 576 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 577 target_compile_features(hwy_contrib PUBLIC cxx_std_11) 578 if (NOT HWY_CXX_STD_TGT_COMPILE_FEATURE STREQUAL "cxx_std_11") 579 target_compile_features(hwy_contrib PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 580 endif() 581 set_target_properties(hwy_contrib PROPERTIES 582 LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version) 583 # For GCC __atomic_store_8, see #887 584 target_link_libraries(hwy_contrib PRIVATE ${ATOMICS_LIBRARIES}) 585 586 # Avoid linker errors if libpthread needs to be linked 587 target_link_libraries(hwy_contrib PRIVATE ${HWY_THREAD_LIBS}) 588 589 if (WIN32 AND NOT MSVC AND NOT HWY_DISABLE_FUTEX) 590 target_link_libraries(hwy_contrib PUBLIC synchronization) 591 endif() 592 593 # not supported by MSVC/Clang, safe to skip (we use DLLEXPORT annotations) 594 if(UNIX AND NOT APPLE) 595 set_property(TARGET hwy_contrib APPEND_STRING PROPERTY 596 LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version") 597 endif() 598 endif() # HWY_ENABLE_CONTRIB 599 600 add_library(hwy_test ${HWY_LIBRARY_TYPE} ${HWY_TEST_SOURCES}) 601 target_link_libraries(hwy_test PUBLIC hwy) 602 target_compile_options(hwy_test PRIVATE ${HWY_FLAGS}) 603 set_property(TARGET hwy_test PROPERTY POSITION_INDEPENDENT_CODE ON) 604 set_target_properties(hwy_test PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION}) 605 target_include_directories(hwy_test PUBLIC 606 $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> 607 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 608 target_compile_features(hwy_test PUBLIC cxx_std_11) 609 if (NOT HWY_CXX_STD_TGT_COMPILE_FEATURE STREQUAL "cxx_std_11") 610 target_compile_features(hwy_test PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 611 endif() 612 set_target_properties(hwy_test PROPERTIES 613 LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version) 614 # not supported by MSVC/Clang, safe to skip (we use DLLEXPORT annotations) 615 if(UNIX AND NOT APPLE) 616 set_property(TARGET hwy_test APPEND_STRING PROPERTY 617 LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/hwy/hwy.version") 618 endif() 619 620 # -------------------------------------------------------- hwy_list_targets 621 # Generate a tool to print the compiled-in targets as defined by the current 622 # flags. This tool will print to stderr at build time, after building hwy. 623 add_executable(hwy_list_targets hwy/tests/list_targets.cc) 624 target_compile_options(hwy_list_targets PRIVATE ${HWY_FLAGS}) 625 target_compile_features(hwy_list_targets PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 626 target_link_libraries(hwy_list_targets PRIVATE hwy) 627 target_include_directories(hwy_list_targets PRIVATE 628 $<TARGET_PROPERTY:hwy,INCLUDE_DIRECTORIES>) 629 # TARGET_FILE always returns the path to executable 630 # Naked target also not always could be run (due to the lack of '.\' prefix) 631 # Thus effective command to run should contain the full path 632 # and emulator prefix (if any). 633 if (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR) 634 add_custom_command(TARGET hwy_list_targets POST_BUILD 635 COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:hwy_list_targets> || (exit 0)) 636 endif() 637 638 # -------------------------------------------------------- 639 # Allow skipping the following sections for projects that do not need them: 640 # tests, examples, benchmarks and installation. 641 642 # -------------------------------------------------------- install library 643 if (HWY_ENABLE_INSTALL) 644 645 install(TARGETS hwy EXPORT hwy_targets 646 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 647 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 648 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") 649 # Install all the headers keeping the relative path to the current directory 650 # when installing them. 651 foreach (source ${HWY_SOURCES}) 652 if ("${source}" MATCHES "\.h$") 653 get_filename_component(dirname "${source}" DIRECTORY) 654 install(FILES "${source}" 655 DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${dirname}") 656 endif() 657 endforeach() 658 659 if (HWY_ENABLE_CONTRIB) 660 install(TARGETS hwy_contrib EXPORT hwy_targets 661 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 662 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 663 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") 664 # Install all the headers keeping the relative path to the current directory 665 # when installing them. 666 foreach (source ${HWY_CONTRIB_SOURCES}) 667 if ("${source}" MATCHES "\.h$") 668 get_filename_component(dirname "${source}" DIRECTORY) 669 install(FILES "${source}" 670 DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${dirname}") 671 endif() 672 endforeach() 673 endif() # HWY_ENABLE_CONTRIB 674 675 if (HWY_ENABLE_TESTS) 676 install(TARGETS hwy_test EXPORT hwy_targets 677 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 678 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 679 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") 680 # Install all the headers keeping the relative path to the current directory 681 # when installing them. 682 foreach (source ${HWY_TEST_SOURCES}) 683 if ("${source}" MATCHES "\.h$") 684 get_filename_component(dirname "${source}" DIRECTORY) 685 install(FILES "${source}" 686 DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${dirname}") 687 endif() 688 endforeach() 689 endif() # HWY_ENABLE_TESTS 690 691 # Add a pkg-config file for libhwy and the contrib/test libraries. 692 set(HWY_LIBRARY_VERSION "${CMAKE_PROJECT_VERSION}") 693 set(HWY_PC_FILES libhwy.pc) 694 695 if (HWY_DISABLE_FUTEX) 696 set(HWY_PC_DISABLE_FUTEX_CFLAGS "-DHWY_DISABLE_FUTEX") 697 else() 698 set(HWY_PC_DISABLE_FUTEX_CFLAGS "") 699 endif() 700 701 if (WIN32 AND NOT MSVC AND NOT HWY_DISABLE_FUTEX) 702 set(HWY_PC_WIN32_SYNCHRONIZATION_LIBS "-lsynchronization") 703 else() 704 set(HWY_PC_WIN32_SYNCHRONIZATION_LIBS "") 705 endif() 706 707 if (HWY_ENABLE_CONTRIB) 708 list(APPEND HWY_PC_FILES libhwy-contrib.pc) 709 endif() # HWY_ENABLE_CONTRIB 710 if (HWY_ENABLE_TESTS) 711 712 if (HWY_TEST_STANDALONE) 713 set(HWY_PC_HWY_TEST_REQUIRES "") 714 set(HWY_PC_HWY_TEST_CFLAGS "-DHWY_TEST_STANDALONE=1") 715 else() 716 set(HWY_PC_HWY_TEST_REQUIRES "gtest") 717 set(HWY_PC_HWY_TEST_CFLAGS "") 718 endif() 719 720 list(APPEND HWY_PC_FILES libhwy-test.pc) 721 endif() # HWY_ENABLE_TESTS 722 foreach (pc ${HWY_PC_FILES}) 723 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${pc}.in" "${pc}" @ONLY) 724 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${pc}" 725 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 726 endforeach() 727 728 endif() # HWY_ENABLE_INSTALL 729 # -------------------------------------------------------- Examples 730 if (HWY_ENABLE_EXAMPLES) 731 732 # Avoids mismatch between GTest's static CRT and our dynamic. 733 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 734 735 # Programming exercise with integrated benchmark 736 add_executable(hwy_benchmark hwy/examples/benchmark.cc) 737 target_sources(hwy_benchmark PRIVATE 738 hwy/nanobenchmark.h) 739 # Try adding one of -DHWY_COMPILE_ONLY_SCALAR, -DHWY_COMPILE_ONLY_EMU128 or 740 # -DHWY_COMPILE_ONLY_STATIC to observe the difference in targets printed. 741 target_compile_options(hwy_benchmark PRIVATE ${HWY_FLAGS}) 742 target_compile_features(hwy_benchmark PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 743 target_link_libraries(hwy_benchmark PRIVATE hwy) 744 target_link_libraries(hwy_benchmark PRIVATE ${ATOMICS_LIBRARIES}) 745 set_target_properties(hwy_benchmark 746 PROPERTIES RUNTIME_OUTPUT_DIRECTORY "examples/") 747 748 # Profiler demo 749 if (HWY_ENABLE_CONTRIB) 750 add_executable(hwy_profiler_example hwy/examples/profiler_example.cc) 751 target_sources(hwy_profiler_example PRIVATE 752 hwy/profiler.h) 753 target_compile_options(hwy_profiler_example PRIVATE ${HWY_FLAGS} ${HWY_THREAD_FLAGS}) 754 target_compile_features(hwy_profiler_example PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 755 target_link_libraries(hwy_profiler_example PRIVATE hwy hwy_contrib) 756 target_link_libraries(hwy_profiler_example PRIVATE ${ATOMICS_LIBRARIES}) 757 target_link_libraries(hwy_profiler_example PRIVATE ${HWY_THREAD_LIBS}) 758 set_target_properties(hwy_profiler_example 759 PROPERTIES RUNTIME_OUTPUT_DIRECTORY "examples/") 760 endif() # HWY_ENABLE_CONTRIB 761 762 endif() # HWY_ENABLE_EXAMPLES 763 # -------------------------------------------------------- Tests 764 765 include(CTest) 766 767 if(BUILD_TESTING AND HWY_ENABLE_TESTS) 768 enable_testing() 769 include(GoogleTest) 770 771 set(HWY_SYSTEM_GTEST OFF CACHE BOOL "Use pre-installed googletest?") 772 773 if(NOT HWY_TEST_STANDALONE) 774 if(HWY_SYSTEM_GTEST) 775 find_package(GTest REQUIRED) 776 else() 777 # Download and unpack googletest at configure time 778 configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) 779 execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . 780 RESULT_VARIABLE result 781 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) 782 if(result) 783 message(FATAL_ERROR "CMake step for googletest failed: ${result}") 784 endif() 785 execute_process(COMMAND ${CMAKE_COMMAND} --build . 786 RESULT_VARIABLE result 787 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) 788 if(result) 789 message(FATAL_ERROR "Build step for googletest failed: ${result}") 790 endif() 791 792 # Prevent overriding the parent project's compiler/linker 793 # settings on Windows 794 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 795 796 # Add googletest directly to our build. This defines 797 # the gtest and gtest_main targets. 798 add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src 799 ${CMAKE_CURRENT_BINARY_DIR}/googletest-build 800 EXCLUDE_FROM_ALL) 801 endif() # HWY_SYSTEM_GTEST 802 endif() # HWY_TEST_STANDALONE 803 804 set(HWY_TEST_FILES 805 hwy/abort_test.cc 806 hwy/aligned_allocator_test.cc 807 hwy/base_test.cc 808 hwy/bit_set_test.cc 809 hwy/highway_test.cc 810 hwy/nanobenchmark_test.cc 811 hwy/perf_counters_test.cc 812 hwy/targets_test.cc 813 hwy/examples/skeleton_test.cc 814 hwy/tests/arithmetic_test.cc 815 hwy/tests/bit_permute_test.cc 816 hwy/tests/blockwise_combine_test.cc 817 hwy/tests/blockwise_shift_test.cc 818 hwy/tests/blockwise_test.cc 819 hwy/tests/cast_test.cc 820 hwy/tests/combine_test.cc 821 hwy/tests/compare_test.cc 822 hwy/tests/complex_arithmetic_test.cc 823 hwy/tests/compress_test.cc 824 hwy/tests/concat_test.cc 825 hwy/tests/convert_test.cc 826 hwy/tests/count_test.cc 827 hwy/tests/crypto_test.cc 828 hwy/tests/demote_test.cc 829 hwy/tests/div_test.cc 830 hwy/tests/dup128_vec_test.cc 831 hwy/tests/expand_test.cc 832 hwy/tests/float_test.cc 833 hwy/tests/fma_test.cc 834 hwy/tests/foreach_vec_test.cc 835 hwy/tests/if_test.cc 836 hwy/tests/in_range_float_to_int_conv_test.cc 837 hwy/tests/interleaved_test.cc 838 hwy/tests/logical_test.cc 839 hwy/tests/mask_combine_test.cc 840 hwy/tests/mask_convert_test.cc 841 hwy/tests/mask_mem_test.cc 842 hwy/tests/mask_set_test.cc 843 hwy/tests/mask_slide_test.cc 844 hwy/tests/mask_test.cc 845 hwy/tests/masked_arithmetic_test.cc 846 hwy/tests/masked_minmax_test.cc 847 hwy/tests/memory_test.cc 848 hwy/tests/minmax_magnitude_test.cc 849 hwy/tests/minmax_number_test.cc 850 hwy/tests/minmax_test.cc 851 hwy/tests/minmax128_test.cc 852 hwy/tests/mul_by_pow2_test.cc 853 hwy/tests/mul_pairwise_test.cc 854 hwy/tests/mul_test.cc 855 hwy/tests/reduction_test.cc 856 hwy/tests/resize_test.cc 857 hwy/tests/reverse_test.cc 858 hwy/tests/rotate_test.cc 859 hwy/tests/saturated_test.cc 860 hwy/tests/shift_test.cc 861 hwy/tests/shuffle4_test.cc 862 hwy/tests/sign_test.cc 863 hwy/tests/slide_up_down_test.cc 864 hwy/tests/sums_abs_diff_test.cc 865 hwy/tests/swizzle_block_test.cc 866 hwy/tests/swizzle_test.cc 867 hwy/tests/table_test.cc 868 hwy/tests/test_util_test.cc 869 hwy/tests/truncate_test.cc 870 hwy/tests/tuple_test.cc 871 hwy/tests/widen_mul_test.cc 872 ) 873 874 set(HWY_TEST_LIBS hwy hwy_test) 875 876 if (HWY_ENABLE_CONTRIB) 877 list(APPEND HWY_TEST_LIBS hwy_contrib) 878 879 list(APPEND HWY_TEST_FILES 880 hwy/auto_tune_test.cc 881 hwy/contrib/algo/copy_test.cc 882 hwy/contrib/algo/find_test.cc 883 hwy/contrib/algo/transform_test.cc 884 hwy/contrib/bit_pack/bit_pack_test.cc 885 hwy/contrib/dot/dot_test.cc 886 hwy/contrib/matvec/matvec_test.cc 887 hwy/contrib/image/image_test.cc 888 # Disabled due to SIGILL in clang7 debug build during gtest discovery phase, 889 # not reproducible locally. Still tested via bazel build. 890 hwy/contrib/math/math_test.cc 891 hwy/contrib/math/math_hyper_test.cc 892 hwy/contrib/math/math_tan_test.cc 893 hwy/contrib/math/math_trig_test.cc 894 hwy/contrib/random/random_test.cc 895 hwy/contrib/sort/bench_sort.cc 896 hwy/contrib/sort/sort_test.cc 897 hwy/contrib/sort/sort_unit_test.cc 898 hwy/contrib/thread_pool/spin_test.cc 899 hwy/contrib/thread_pool/thread_pool_test.cc 900 hwy/contrib/thread_pool/topology_test.cc 901 hwy/contrib/unroller/unroller_test.cc 902 ) 903 endif() # HWY_ENABLE_CONTRIB 904 905 if(HWY_TEST_STANDALONE) 906 set(HWY_GTEST_LIBS "") 907 else() 908 if(HWY_SYSTEM_GTEST) 909 if (CMAKE_VERSION VERSION_LESS 3.20) 910 set(HWY_GTEST_LIBS GTest::GTest GTest::Main) 911 else() 912 set(HWY_GTEST_LIBS GTest::gtest GTest::gtest_main) 913 endif() 914 else() 915 set(HWY_GTEST_LIBS gtest gtest_main) 916 endif() 917 endif() # HWY_TEST_STANDALONE 918 919 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests) 920 foreach (TESTFILE IN LISTS HWY_TEST_FILES) 921 # The TESTNAME is the name without the extension or directory. 922 get_filename_component(TESTNAME ${TESTFILE} NAME_WE) 923 add_executable(${TESTNAME} ${TESTFILE}) 924 target_compile_options(${TESTNAME} PRIVATE ${HWY_FLAGS} ${HWY_THREAD_FLAGS}) 925 # Test all targets, not just the best/baseline. This changes the default 926 # policy to all-attainable; note that setting -DHWY_COMPILE_* directly can 927 # cause compile errors because only one may be set, and other CMakeLists.txt 928 # that include us may set them. 929 target_compile_options(${TESTNAME} PRIVATE -DHWY_IS_TEST=1) 930 if(HWY_TEST_STANDALONE) 931 target_compile_options(${TESTNAME} PRIVATE -DHWY_TEST_STANDALONE=1) 932 endif() 933 target_compile_features(${TESTNAME} PRIVATE ${HWY_CXX_STD_TGT_COMPILE_FEATURE}) 934 935 target_link_libraries(${TESTNAME} PRIVATE ${HWY_TEST_LIBS} ${HWY_GTEST_LIBS}) 936 # For GCC __atomic_store_8, see #887 937 target_link_libraries(${TESTNAME} PRIVATE ${ATOMICS_LIBRARIES}) 938 939 # Avoid linker errors if libpthread needs to be linked 940 target_link_libraries(${TESTNAME} PRIVATE ${HWY_THREAD_LIBS}) 941 942 # Output test targets in the test directory. 943 set_target_properties(${TESTNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "tests") 944 945 if (HWY_EMSCRIPTEN) 946 set_target_properties(${TESTNAME} PROPERTIES LINK_FLAGS "-s SINGLE_FILE=1") 947 endif() 948 949 if(${CMAKE_VERSION} VERSION_LESS "3.10.3") 950 gtest_discover_tests(${TESTNAME} TIMEOUT 60) 951 else () 952 gtest_discover_tests(${TESTNAME} DISCOVERY_TIMEOUT 60) 953 endif () 954 endforeach () 955 956 # The skeleton test uses the skeleton library code. 957 target_sources(skeleton_test PRIVATE hwy/examples/skeleton.cc) 958 959 endif() # BUILD_TESTING 960 961 if (HWY_ENABLE_INSTALL) 962 # write hwy-config file to handle `Config` mode 963 include(CMakePackageConfigHelpers) 964 write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/hwy-config-version.cmake" COMPATIBILITY SameMajorVersion) 965 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/hwy-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/hwy") 966 install(EXPORT hwy_targets NAMESPACE "${namespace}" FILE hwy-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/hwy") 967 endif()