CMakeLists.txt (14894B)
1 # Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) 2 # This file is part of KFR 3 # 4 # KFR is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 2 of the License, or 7 # (at your option) any later version. 8 # 9 # KFR is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with KFR. 16 17 cmake_minimum_required(VERSION 3.12) 18 19 if (KFR_WITH_CLANG) 20 set(CLANG_VERSION 17.0.6) 21 if (WIN32) 22 set(CLANG_URL 23 https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/LLVM-${CLANG_VERSION}-win64.exe 24 ) 25 set(CLANG_ARCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/clang-prebuilt.exe") 26 set(CLANG_DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/clang") 27 28 set(SEVENZIP_URL https://www.7-zip.org/a/7z2301-x64.msi) 29 set(SEVENZIP_ARCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/7z2301-x64.msi") 30 set(SEVENZIP_DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/7z") 31 message(STATUS "Downloading 7zip from ${SEVENZIP_URL}") 32 file( 33 DOWNLOAD ${SEVENZIP_URL} ${SEVENZIP_ARCH_FILE} 34 EXPECTED_HASH 35 SHA256=0BA639B6DACDF573D847C911BD147C6384381A54DAC082B1E8C77BC73D58958B 36 SHOW_PROGRESS) 37 38 cmake_path(NATIVE_PATH SEVENZIP_ARCH_FILE NORMALIZE 39 SEVENZIP_ARCH_FILE_W) 40 cmake_path(NATIVE_PATH SEVENZIP_DEST_DIR NORMALIZE SEVENZIP_DEST_DIR_W) 41 execute_process(COMMAND msiexec /a "${SEVENZIP_ARCH_FILE_W}" 42 "TARGETDIR=${SEVENZIP_DEST_DIR_W}" /qn) 43 44 message(STATUS "Downloading Clang ${CLANG_VERSION} from ${CLANG_URL}") 45 file( 46 DOWNLOAD ${CLANG_URL} ${CLANG_ARCH_FILE} 47 EXPECTED_HASH 48 SHA256=89dc351af8e8fa1cafc6b48411e608aa9457c930a10f984aad5d21ab020165b2 49 SHOW_PROGRESS) 50 51 message(STATUS "Unpacking Clang ${CLANG_VERSION}") 52 execute_process( 53 COMMAND ${SEVENZIP_DEST_DIR}/Files/7-Zip/7z.exe x -bb0 -bd -aos 54 -o${CLANG_DEST_DIR} ${CLANG_ARCH_FILE} OUTPUT_QUIET) 55 56 set(CMAKE_CXX_COMPILER 57 ${CLANG_DEST_DIR}/bin/clang-cl.exe 58 CACHE STRING "Clang" FORCE) 59 set(CMAKE_C_COMPILER 60 ${CLANG_DEST_DIR}/bin/clang-cl.exe 61 CACHE STRING "Clang" FORCE) 62 endif () 63 if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") 64 set(CLANG_URL 65 https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-22.04.tar.xz 66 ) 67 set(CLANG_ARCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/clang-prebuilt.tar.xz") 68 set(CLANG_DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/clang") 69 message(STATUS "Downloading Clang ${CLANG_VERSION} from ${CLANG_URL}") 70 file( 71 DOWNLOAD ${CLANG_URL} ${CLANG_ARCH_FILE} 72 EXPECTED_HASH 73 SHA256=884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3 74 SHOW_PROGRESS) 75 message(STATUS "Unpacking Clang ${CLANG_VERSION}") 76 file(ARCHIVE_EXTRACT INPUT ${CLANG_ARCH_FILE} DESTINATION 77 ${CLANG_DEST_DIR}) 78 set(CMAKE_CXX_COMPILER 79 ${CLANG_DEST_DIR}/clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-22.04/bin/clang++ 80 CACHE STRING "Clang" FORCE) 81 set(CMAKE_C_COMPILER 82 ${CLANG_DEST_DIR}/clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-22.04/bin/clang 83 CACHE STRING "Clang" FORCE) 84 endif () 85 message(STATUS "Clang ${CLANG_VERSION} is set up successfully") 86 endif () 87 88 file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/include/kfr/kfr.h KFR_VERSION 89 REGEX "#define KFR_VERSION_(MINOR|MAJOR|PATCH)") 90 string(REGEX MATCHALL "[0-9]+" KFR_VERSION_MATCH ${KFR_VERSION}) 91 string(REPLACE ";" "." KFR_VERSION "${KFR_VERSION_MATCH}") 92 93 project( 94 kfr 95 VERSION ${KFR_VERSION} 96 LANGUAGES CXX) 97 98 if (DEBUG_CMAKE) 99 get_cmake_property(VARS VARIABLES) 100 list (SORT VARS) 101 foreach (VAR ${VARS}) 102 message(STATUS "${VAR}=${${VAR}}") 103 endforeach() 104 endif () 105 106 set(CMAKE_CXX_STANDARD 17) 107 set(CMAKE_CXX_STANDARD_REQUIRED ON) 108 set(CMAKE_CXX_EXTENSIONS ON) 109 110 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin) 111 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${PROJECT_BINARY_DIR}/bin) 112 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/bin) 113 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/lib) 114 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${PROJECT_BINARY_DIR}/lib) 115 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/lib) 116 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/lib) 117 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${PROJECT_BINARY_DIR}/lib) 118 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/lib) 119 120 if (CPU_ARCH) 121 if (NOT KFR_ARCH) 122 message( 123 WARNING 124 "CPU_ARCH is deprecated. Use KFR_ARCH instead. KFR will use machine native architecture by default" 125 ) 126 else () 127 message( 128 WARNING 129 "Both KFR_ARCH and CPU_ARCH are defined. KFR will use architecture set by KFR_ARCH (${KFR_ARCH})" 130 ) 131 endif () 132 endif () 133 134 if (EMSCRIPTEN) 135 set(KFR_ARCH "sse41" CACHE STRING "") 136 set(KFR_ENABLE_MULTIARCH OFF CACHE BOOL "") 137 endif () 138 139 set(X86 FALSE) 140 if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") 141 set(X86 TRUE) 142 endif () 143 if (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") 144 set(X86 TRUE) 145 endif () 146 if (CMAKE_OSX_ARCHITECTURES MATCHES "^[Aa][Rr][Mm]64$") 147 set(X86 FALSE) 148 endif () 149 150 if (CMAKE_CXX_COMPILER_TARGET MATCHES "^arm") 151 set(X86 FALSE) 152 endif () 153 154 if (CMAKE_ANDROID_ARCH_ABI MATCHES "x86") 155 set(X86 TRUE) 156 endif () 157 158 if (CMAKE_SIZEOF_VOID_P EQUAL 8) 159 set(BITNESS64 TRUE) 160 else () 161 set(BITNESS64 FALSE) 162 endif () 163 164 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL 165 "AppleClang") 166 set(CLANG 1) 167 else () 168 set(CLANG 0) 169 endif () 170 171 include(cmake/target_set_arch.cmake) 172 include(cmake/link_as_whole.cmake) 173 include(cmake/add_kfr_library.cmake) 174 175 # Include autogenerated list of source files 176 include(sources.cmake) 177 include(CMakeDependentOption) 178 179 option(KFR_ENABLE_MULTIARCH 180 "Multiple architectures will be built with runtime dispatch" ON) 181 182 option(ENABLE_TESTS "Enable KFR tests" OFF) 183 cmake_dependent_option(ENABLE_EXAMPLES "Enable KFR examples" ON "ENABLE_TESTS" 184 OFF) 185 if (CLANG) 186 option(KFR_ENABLE_DFT "Enable DFT and related algorithms." ON) 187 else () 188 option(KFR_ENABLE_DFT "Enable DFT and related algorithms." OFF) 189 endif () 190 option(KFR_ENABLE_ASMTEST "Enable writing disassembly" OFF) 191 option(KFR_REGENERATE_TESTS "Regenerate auto tests" OFF) 192 option(KFR_DISABLE_CLANG_EXTENSIONS "Disable Clang vector extensions" OFF) 193 option(KFR_EXTENDED_TESTS "Extended tests (up to hour)" OFF) 194 option(KFR_SKIP_TESTS "Build tests but don't run tests" OFF) 195 option(KFR_ENABLE_CAPI_BUILD "Enable KFR C API building" OFF) 196 option(KFR_INSTALL_HEADERS "Include headers in installation" ON) 197 option(KFR_INSTALL_LIBRARIES "Include libraries in installation" ON) 198 mark_as_advanced(KFR_ENABLE_ASMTEST) 199 mark_as_advanced(KFR_REGENERATE_TESTS) 200 mark_as_advanced(KFR_DISABLE_CLANG_EXTENSIONS) 201 202 if (CMAKE_ANDROID_ARCH_ABI) 203 set(KFR_ENABLE_MULTIARCH OFF CACHE INTERNAL "" FORCE) 204 endif () 205 206 if (KFR_ENABLE_CAPI_BUILD AND NOT KFR_ENABLE_DFT) 207 message( 208 FATAL_ERROR 209 "KFR_ENABLE_CAPI_BUILD requires KFR_ENABLE_DFT to be enabled") 210 endif () 211 212 if (NOT KFR_ARCH) 213 set(KFR_ARCH target) 214 endif () 215 216 if (KFR_ARCH STREQUAL "detect") 217 set(KFR_ARCH host) 218 endif () 219 220 set(DETECT_NAMES host target) 221 if (X86) 222 set(ALLOWED_ARCHS 223 generic 224 sse 225 sse2 226 sse3 227 ssse3 228 sse41 229 sse42 230 avx 231 avx2 232 avx512) 233 else () 234 set(ALLOWED_ARCHS generic neon neon64) 235 endif () 236 237 if (NOT X86) 238 if (KFR_ARCH IN_LIST DETECT_NAMES) 239 if (BITNESS64) 240 set(KFR_ARCH neon64) 241 else () 242 set(KFR_ARCH neon) 243 endif () 244 endif () 245 endif () 246 247 if (KFR_ARCH IN_LIST DETECT_NAMES AND NOT CMAKE_CROSSCOMPILING) 248 message(STATUS "Detecting ${KFR_ARCH} architecture") 249 try_run( 250 RUN_RESULT COMPILE_RESULT "${CMAKE_CURRENT_BINARY_DIR}/tmpdir" 251 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/detect_cpu.cpp 252 CMAKE_FLAGS 253 "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}/include" 254 -DCMAKE_CXX_STANDARD=17 255 -DCMAKE_CXX_STANDARD_REQUIRED=ON 256 "-DCOMPILE_DEFINITIONS=-DCPU_${KFR_ARCH}=1" 257 -DCMAKE_CXX_EXTENSIONS=ON 258 COMPILE_OUTPUT_VARIABLE COMPILE_OUT 259 RUN_OUTPUT_VARIABLE RUN_OUT) 260 if (COMPILE_RESULT AND RUN_RESULT EQUAL 0) 261 message( 262 STATUS 263 "Default CPU architecture for KFR is ${RUN_OUT} (set KFR_ARCH to override)" 264 ) 265 set(KFR_ARCH 266 ${RUN_OUT} 267 CACHE INTERNAL "Detected CPU" FORCE) 268 else () 269 message(STATUS COMPILE_RESULT = ${COMPILE_RESULT}) 270 message(STATUS RUN_RESULT = ${RUN_RESULT}) 271 message(STATUS COMPILE_OUT = ${COMPILE_OUT}) 272 message(FATAL_ERROR RUN_OUT = ${RUN_OUT}) 273 endif () 274 else () 275 message( 276 STATUS 277 "Default CPU architecture for KFR is ${KFR_ARCH} (set by KFR_ARCH)") 278 endif () 279 280 281 if (X86 AND KFR_ARCH STREQUAL "target") 282 set(KFR_ARCH sse2 CACHE INTERNAL "Default CPU" FORCE) 283 endif () 284 285 if (NOT KFR_ARCH IN_LIST ALLOWED_ARCHS) 286 message(FATAL_ERROR "Incorrect architecture set by KFR_ARCH: ${KFR_ARCH}") 287 endif () 288 289 if (NOT KFR_ARCHS) 290 if (X86) 291 if (APPLE) 292 set(KFR_ARCHS sse41 avx avx2 avx512) 293 else () 294 set(KFR_ARCHS sse2 sse41 avx avx2 avx512) 295 endif () 296 else () 297 set(KFR_ARCHS ${KFR_ARCH}) 298 endif () 299 endif () 300 301 if (KFR_ENABLE_MULTIARCH) 302 message( 303 STATUS 304 "Runtime dispatch is enabled for architectures: ${KFR_ARCHS} (set KFR_ARCHS to change, set KFR_ENABLE_MULTIARCH=OFF to disable)" 305 ) 306 else () 307 message( 308 STATUS 309 "Runtime dispatch is disabled. Set KFR_ENABLE_MULTIARCH=ON to enable" 310 ) 311 endif () 312 313 string(REPLACE ";" ", " KFR_ARCHS_COMMA "${KFR_ARCHS}") 314 315 if (KFR_ENABLE_MULTIARCH) 316 add_compile_definitions(KFR_ENABLED_ARCHS="${KFR_ARCHS_COMMA}") 317 endif () 318 319 add_library(use_arch INTERFACE) 320 target_set_arch(use_arch INTERFACE ${KFR_ARCH}) 321 322 if (WIN32) 323 add_definitions(-D_CRT_SECURE_NO_WARNINGS) 324 add_definitions(-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) 325 add_definitions(-D_ENABLE_EXTENDED_ALIGNED_STORAGE) 326 endif () 327 328 set(STD_LIB) 329 if (NOT IOS AND NOT ANDROID) 330 set(STD_LIB stdc++) 331 endif () 332 333 if (ANDROID) 334 set(PTHREAD_LIB) 335 else () 336 set(PTHREAD_LIB pthread) 337 endif () 338 339 # KFR library 340 add_library(kfr INTERFACE) 341 # target_sources(kfr INTERFACE ${KFR_SRC}) 342 target_include_directories( 343 kfr INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 344 $<INSTALL_INTERFACE:include>) 345 target_compile_options(kfr INTERFACE "$<$<CONFIG:DEBUG>:-DKFR_DEBUG>") 346 if (APPLE) 347 target_compile_options(kfr INTERFACE -faligned-allocation) 348 endif () 349 350 if (EMSCRIPTEN) 351 target_compile_options(kfr INTERFACE -msimd128) 352 endif () 353 354 if (MSVC) 355 target_compile_options(kfr INTERFACE -bigobj) 356 else () 357 target_link_libraries(kfr INTERFACE ${STD_LIB} ${PTHREAD_LIB} m) 358 endif () 359 if (KFR_DISABLE_CLANG_EXTENSIONS) 360 target_compile_definitions(kfr INTERFACE -DCMT_DISABLE_CLANG_EXT) 361 endif () 362 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 363 add_compile_options(-Wno-ignored-qualifiers -Wno-psabi) 364 endif () 365 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 366 add_compile_options(-Wno-c++1z-extensions -Wno-psabi 367 -Wno-unknown-warning-option) 368 endif () 369 if (MSVC) 370 add_compile_options(/wd4141) 371 target_compile_options(kfr INTERFACE $<$<CXX_COMPILER_ID:MSVC>:/Zc:lambda>) 372 endif () 373 374 if (NOT KFR_ENABLE_DFT) 375 target_compile_definitions(kfr INTERFACE -DKFR_NO_DFT) 376 endif () 377 if (KFR_EXTENDED_TESTS) 378 target_compile_definitions(kfr INTERFACE -DKFR_EXTENDED_TESTS) 379 endif () 380 381 set(KFR_DEBUG_INSTALL_SUFFIX "/debug" CACHE STRING "") 382 383 add_subdirectory(src/dsp) 384 add_subdirectory(src/io) 385 if (KFR_ENABLE_DFT) 386 add_subdirectory(src/dft) 387 endif () 388 if (KFR_ENABLE_CAPI_BUILD) 389 add_subdirectory(src/capi) 390 endif () 391 392 if (ENABLE_EXAMPLES) 393 add_subdirectory(examples) 394 add_subdirectory(tools) 395 endif () 396 if (ENABLE_TESTS) 397 add_subdirectory(tests) 398 endif () 399 400 set(kfr_defines) 401 402 function (append_defines_from target) 403 get_target_property(compile_defs ${target} INTERFACE_COMPILE_DEFINITIONS) 404 if (compile_defs) 405 list(APPEND kfr_defines "${compile_defs}") 406 endif () 407 set(kfr_defines 408 ${kfr_defines} 409 PARENT_SCOPE) 410 endfunction () 411 412 append_defines_from(kfr) 413 if (KFR_ENABLE_DFT) 414 append_defines_from(kfr_dft) 415 endif () 416 append_defines_from(kfr_io) 417 418 string(REPLACE "=" " " kfr_defines "${kfr_defines}") 419 string(REPLACE ";" "\n#define " kfr_defines "${kfr_defines}") 420 if (kfr_defines) 421 set(kfr_defines "#define ${kfr_defines}\n") 422 endif () 423 424 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/kfr_config.h "${kfr_defines}") 425 426 if (KFR_INSTALL_HEADERS) 427 install(DIRECTORY include/kfr DESTINATION include) 428 429 install( 430 FILES ${CMAKE_CURRENT_BINARY_DIR}/kfr_config.h 431 DESTINATION include/kfr 432 RENAME config.h) 433 endif () 434 435 # uninstall target 436 if (NOT TARGET uninstall) 437 configure_file( 438 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" 439 "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" IMMEDIATE 440 @ONLY) 441 442 add_custom_target( 443 uninstall 444 COMMAND ${CMAKE_COMMAND} -P 445 ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake) 446 endif () 447 448 include(GNUInstallDirs) 449 include(CMakePackageConfigHelpers) 450 451 set(KFR_INSTALL_CMAKEDIR 452 "${CMAKE_INSTALL_LIBDIR}/cmake/kfr" 453 CACHE STRING "Path to KFR CMake files") 454 455 configure_package_config_file( 456 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake.in 457 "${CMAKE_CURRENT_BINARY_DIR}/KFRConfig.cmake" 458 INSTALL_DESTINATION "lib/cmake/kfr" 459 NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO) 460 461 install(TARGETS kfr EXPORT kfr_export) 462 463 install( 464 EXPORT kfr_export 465 DESTINATION "${KFR_INSTALL_CMAKEDIR}" 466 CONFIGURATIONS Debug Release 467 FILE KFRConfig.cmake) 468 469 write_basic_package_version_file(KFRConfigVersion.cmake 470 VERSION ${KFR_VERSION} 471 COMPATIBILITY SameMinorVersion) 472 473 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KFRConfigVersion.cmake" 474 DESTINATION 475 "${KFR_INSTALL_CMAKEDIR}" )