CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. cmake_minimum_required(VERSION 3.1)
  2. include(opus_functions.cmake)
  3. get_library_version(OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR)
  4. message(STATUS "Opus library version: ${OPUS_LIBRARY_VERSION}")
  5. get_package_version(PACKAGE_VERSION)
  6. message(STATUS "Opus package version: ${PACKAGE_VERSION}")
  7. string(REGEX
  8. REPLACE "^([0-9]+.[0-9]+\\.?([0-9]+)?).*"
  9. "\\1"
  10. PROJECT_VERSION
  11. ${PACKAGE_VERSION})
  12. message(STATUS "Opus project version: ${PROJECT_VERSION}")
  13. project(Opus LANGUAGES C VERSION ${PROJECT_VERSION})
  14. include(opus_buildtype.cmake)
  15. option(OPUS_STACK_PROTECTOR "Use stack protection" ON)
  16. option(OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)" OFF)
  17. option(OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames"
  18. OFF)
  19. option(OPUS_BUILD_PROGRAMS "Build programs" OFF)
  20. option(OPUS_FIXED_POINT
  21. "Compile as fixed-point (for machines without a fast enough FPU)" OFF)
  22. option(OPUS_ENABLE_FLOAT_API
  23. "Compile with the floating point API (for machines with float library"
  24. ON)
  25. option(OPUS_INSTALL_PKG_CONFIG_MODULE "Install PkgConfig module" ON)
  26. option(OPUS_INSTALL_CMAKE_CONFIG_MODULE "Install CMake package config module"
  27. ON)
  28. include(opus_config.cmake)
  29. include(opus_sources.cmake)
  30. include(GNUInstallDirs)
  31. include(CMakeDependentOption)
  32. include(FeatureSummary)
  33. if(OPUS_STACK_PROTECTOR)
  34. if(NOT MSVC) # GC on by default on MSVC
  35. check_and_set_flag(STACK_PROTECTION_STRONG -fstack-protector-strong)
  36. endif()
  37. else()
  38. if(MSVC)
  39. check_and_set_flag(BUFFER_SECURITY_CHECK /GS-)
  40. endif()
  41. endif()
  42. if(OPUS_CPU_X86 OR OPUS_CPU_X64)
  43. cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE
  44. "Does runtime check for SSE1 support"
  45. ON
  46. "SSE1_SUPPORTED"
  47. OFF)
  48. cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE2
  49. "Does runtime check for SSE2 support"
  50. ON
  51. "SSE2_SUPPORTED"
  52. OFF)
  53. cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE4_1
  54. "Does runtime check for SSE4.1 support"
  55. ON
  56. "SSE4_1_SUPPORTED"
  57. OFF)
  58. cmake_dependent_option(OPUS_X86_MAY_HAVE_AVX
  59. "Does runtime check for AVX support"
  60. ON
  61. "AVX_SUPPORTED"
  62. OFF)
  63. if(OPUS_CPU_X64) # Assume 64 bit has SSE2 support
  64. cmake_dependent_option(OPUS_X86_PRESUME_SSE
  65. "Assume target CPU has SSE1 support"
  66. ON
  67. "OPUS_X86_MAY_HAVE_SSE"
  68. OFF)
  69. cmake_dependent_option(OPUS_X86_PRESUME_SSE2
  70. "Assume target CPU has SSE2 support"
  71. ON
  72. "OPUS_X86_MAY_HAVE_SSE2"
  73. OFF)
  74. else()
  75. cmake_dependent_option(OPUS_X86_PRESUME_SSE
  76. "Assume target CPU has SSE1 support"
  77. OFF
  78. "OPUS_X86_MAY_HAVE_SSE"
  79. OFF)
  80. cmake_dependent_option(OPUS_X86_PRESUME_SSE2
  81. "Assume target CPU has SSE2 support"
  82. OFF
  83. "OPUS_X86_MAY_HAVE_SSE2"
  84. OFF)
  85. endif()
  86. cmake_dependent_option(OPUS_X86_PRESUME_SSE4_1
  87. "Assume target CPU has SSE4.1 support"
  88. OFF
  89. "OPUS_X86_MAY_HAVE_SSE4_1"
  90. OFF)
  91. cmake_dependent_option(OPUS_X86_PRESUME_AVX
  92. "Assume target CPU has AVX support"
  93. OFF
  94. "OPUS_X86_MAY_HAVE_AVX"
  95. OFF)
  96. endif()
  97. set_package_properties(Git
  98. PROPERTIES
  99. TYPE
  100. REQUIRED
  101. DESCRIPTION
  102. "fast, scalable, distributed revision control system"
  103. URL
  104. "https://git-scm.com/"
  105. PURPOSE
  106. "required to set up package version")
  107. add_feature_info(STACK_PROTECTOR OPUS_STACK_PROTECTOR "Use stack protection")
  108. add_feature_info(USE_ALLOCA OPUS_USE_ALLOCA
  109. "Use alloca for stack arrays (on non-C99 compilers)")
  110. add_feature_info(CUSTOM_MODES OPUS_CUSTOM_MODES
  111. "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames")
  112. add_feature_info(BUILD_PROGRAMS OPUS_BUILD_PROGRAMS "Build programs")
  113. add_feature_info(
  114. FIXED_POINT OPUS_FIXED_POINT
  115. "compile as fixed-point (for machines without a fast enough FPU)")
  116. add_feature_info(
  117. FLOAT_API OPUS_ENABLE_FLOAT_API
  118. "compile with the floating point API (for machines with float library)")
  119. add_feature_info(INSTALL_PKG_CONFIG_MODULE OPUS_INSTALL_PKG_CONFIG_MODULE
  120. "install PkgConfig module")
  121. add_feature_info(INSTALL_CMAKE_CONFIG_MODULE OPUS_INSTALL_CMAKE_CONFIG_MODULE
  122. "install CMake package config module")
  123. if(OPUS_CPU_X86 OR OPUS_CPU_X64)
  124. add_feature_info(X86_MAY_HAVE_SSE OPUS_X86_MAY_HAVE_SSE
  125. "does runtime check for SSE1 support")
  126. add_feature_info(X86_MAY_HAVE_SSE2 OPUS_X86_MAY_HAVE_SSE2
  127. "does runtime check for SSE2 support")
  128. add_feature_info(X86_MAY_HAVE_SSE4_1 OPUS_X86_MAY_HAVE_SSE4_1
  129. "does runtime check for SSE4_1 support")
  130. add_feature_info(X86_MAY_HAVE_AVX OPUS_X86_MAY_HAVE_AVX
  131. "does runtime check for AVX support")
  132. add_feature_info(X86_PRESUME_SSE OPUS_X86_PRESUME_SSE
  133. "assume target CPU has SSE1 support")
  134. add_feature_info(X86_PRESUME_SSE2 OPUS_X86_PRESUME_SSE2
  135. "assume target CPU has SSE2 support")
  136. add_feature_info(X86_PRESUME_SSE4_1 OPUS_X86_PRESUME_SSE4_1
  137. "assume target CPU has SSE4_1 support")
  138. add_feature_info(X86_PRESUME_AVX OPUS_X86_PRESUME_AVX
  139. "assume target CPU has AVX support")
  140. endif()
  141. feature_summary(WHAT ALL)
  142. add_library(opus ${opus_sources} ${opus_sources_float})
  143. set(Opus_PUBLIC_HEADER
  144. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus.h
  145. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_custom.h
  146. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_defines.h
  147. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_multistream.h
  148. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_projection.h
  149. ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_types.h)
  150. set_target_properties(opus
  151. PROPERTIES SOVERSION
  152. ${OPUS_LIBRARY_VERSION_MAJOR}
  153. VERSION
  154. ${OPUS_LIBRARY_VERSION}
  155. PUBLIC_HEADER
  156. "${Opus_PUBLIC_HEADER}")
  157. target_include_directories(
  158. opus
  159. PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  160. $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  161. PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
  162. ${CMAKE_CURRENT_SOURCE_DIR}
  163. celt
  164. silk)
  165. target_link_libraries(opus PRIVATE ${OPUS_REQUIRED_LIBRARIES})
  166. target_compile_definitions(opus PRIVATE OPUS_BUILD ENABLE_HARDENING)
  167. if(NOT MSVC)
  168. target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=2)
  169. endif()
  170. # It is strongly recommended to uncomment one of these VAR_ARRAYS: Use C99
  171. # variable-length arrays for stack allocation USE_ALLOCA: Use alloca() for stack
  172. # allocation If none is defined, then the fallback is a non-threadsafe global
  173. # array
  174. if(OPUS_USE_ALLOCA OR MSVC)
  175. target_compile_definitions(opus PRIVATE USE_ALLOCA)
  176. else()
  177. target_compile_definitions(opus PRIVATE VAR_ARRAYS)
  178. endif()
  179. if(OPUS_CUSTOM_MODES)
  180. target_compile_definitions(opus PRIVATE CUSTOM_MODES)
  181. endif()
  182. if(BUILD_SHARED_LIBS)
  183. if(WIN32)
  184. target_compile_definitions(opus PRIVATE DLL_EXPORT)
  185. else()
  186. include(CheckCCompilerFlag)
  187. check_c_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
  188. if(COMPILER_HAS_HIDDEN_VISIBILITY)
  189. set_target_properties(opus PROPERTIES C_VISIBILITY_PRESET hidden)
  190. endif()
  191. endif()
  192. endif()
  193. add_sources_group(opus silk ${silk_sources})
  194. add_sources_group(opus celt ${celt_sources})
  195. if(OPUS_FIXED_POINT)
  196. add_sources_group(opus silk ${silk_sources_fixed})
  197. target_include_directories(opus PRIVATE silk/fixed)
  198. target_compile_definitions(opus PRIVATE FIXED_POINT=1)
  199. else()
  200. add_sources_group(opus silk ${silk_sources_float})
  201. target_include_directories(opus PRIVATE silk/float)
  202. endif()
  203. if(NOT OPUS_ENABLE_FLOAT_API)
  204. target_compile_definitions(opus PRIVATE DISABLE_FLOAT_API)
  205. endif()
  206. if(OPUS_X86_MAY_HAVE_SSE
  207. OR OPUS_X86_MAY_HAVE_SSE2
  208. OR OPUS_X86_MAY_HAVE_SSE4_1
  209. OR OPUS_X86_MAY_HAVE_AVX)
  210. target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD)
  211. endif()
  212. if(OPUS_X86_MAY_HAVE_SSE)
  213. add_sources_group(opus celt ${celt_sources_sse})
  214. target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE)
  215. endif()
  216. if(OPUS_X86_PRESUME_SSE)
  217. target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE)
  218. endif()
  219. if(OPUS_X86_MAY_HAVE_SSE2)
  220. add_sources_group(opus celt ${celt_sources_sse2})
  221. target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE2)
  222. endif()
  223. if(OPUS_X86_PRESUME_SSE2)
  224. target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE2)
  225. endif()
  226. if(OPUS_X86_MAY_HAVE_SSE)
  227. add_sources_group(opus celt ${celt_sources_sse4_1})
  228. add_sources_group(opus silk ${silk_sources_sse4_1})
  229. if(OPUS_FIXED_POINT)
  230. add_sources_group(opus silk ${silk_sources_fixed_sse4_1})
  231. endif()
  232. target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE4_1)
  233. endif()
  234. if(OPUS_X86_PRESUME_SSE4_1)
  235. target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE4_1)
  236. endif()
  237. if(CMAKE_SYSTEM_PROCESSOR MATCHES "(armv7-a)")
  238. add_sources_group(opus celt ${celt_sources_arm})
  239. endif()
  240. if(COMPILER_SUPPORT_NEON AND OPUS_USE_NEON)
  241. if(OPUS_MAY_HAVE_NEON)
  242. if(RUNTIME_CPU_CAPABILITY_DETECTION)
  243. message(STATUS "OPUS_MAY_HAVE_NEON enabling runtime detection")
  244. target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD)
  245. else()
  246. message(ERROR "Runtime cpu capability detection needed for MAY_HAVE_NEON")
  247. endif()
  248. # Do runtime check for NEON
  249. target_compile_definitions(opus
  250. PRIVATE
  251. OPUS_ARM_MAY_HAVE_NEON
  252. OPUS_ARM_MAY_HAVE_NEON_INTR)
  253. endif()
  254. add_sources_group(opus celt ${celt_sources_arm_neon_intr})
  255. add_sources_group(opus silk ${silk_sources_arm_neon_intr})
  256. # silk arm neon depends on main_Fix.h
  257. target_include_directories(opus PRIVATE silk/fixed)
  258. if(OPUS_FIXED_POINT)
  259. add_sources_group(opus silk ${silk_sources_fixed_arm_neon_intr})
  260. endif()
  261. if(OPUS_PRESUME_NEON)
  262. target_compile_definitions(opus
  263. PRIVATE
  264. OPUS_ARM_PRESUME_NEON
  265. OPUS_ARM_PRESUME_NEON_INTR)
  266. endif()
  267. endif()
  268. install(TARGETS opus
  269. EXPORT OpusTargets
  270. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  271. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  272. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  273. PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
  274. if(OPUS_INSTALL_PKG_CONFIG_MODULE)
  275. set(prefix ${CMAKE_INSTALL_PREFIX})
  276. set(exec_prefix ${CMAKE_INSTALL_PREFIX})
  277. set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
  278. set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
  279. set(VERSION ${OPUS_LIBRARY_VERSION})
  280. set(VERSION ${OPUS_LIBRARY_VERSION})
  281. if(HAVE_LIBM)
  282. set(LIBM "-lm")
  283. endif()
  284. configure_file(opus.pc.in opus.pc)
  285. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
  286. DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
  287. endif()
  288. if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
  289. set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
  290. install(EXPORT OpusTargets
  291. NAMESPACE Opus::
  292. DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
  293. include(CMakePackageConfigHelpers)
  294. set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
  295. configure_package_config_file(OpusConfig.cmake.in
  296. OpusConfig.cmake
  297. INSTALL_DESTINATION
  298. ${CMAKE_INSTALL_PACKAGEDIR}
  299. PATH_VARS
  300. INCLUDE_INSTALL_DIR
  301. INSTALL_PREFIX
  302. ${CMAKE_INSTALL_PREFIX})
  303. write_basic_package_version_file(OpusConfigVersion.cmake
  304. VERSION ${PROJECT_VERSION}
  305. COMPATIBILITY SameMajorVersion)
  306. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
  307. ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
  308. DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
  309. endif()
  310. if(OPUS_BUILD_PROGRAMS)
  311. # demo
  312. if(OPUS_CUSTOM_MODES)
  313. add_executable(opus_custom_demo ${opus_custom_demo_sources})
  314. target_include_directories(opus_custom_demo
  315. PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  316. target_link_libraries(opus_custom_demo PRIVATE opus)
  317. endif()
  318. add_executable(opus_demo ${opus_demo_sources})
  319. target_include_directories(opus_demo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  320. target_include_directories(opus_demo PRIVATE silk) # debug.h
  321. target_include_directories(opus_demo PRIVATE celt) # arch.h
  322. target_link_libraries(opus_demo PRIVATE opus)
  323. # compare
  324. add_executable(opus_compare ${opus_compare_sources})
  325. target_include_directories(opus_compare PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  326. target_link_libraries(opus_compare PRIVATE opus)
  327. endif()
  328. if(BUILD_TESTING)
  329. enable_testing()
  330. # tests
  331. add_executable(test_opus_decode ${test_opus_decode_sources})
  332. target_include_directories(test_opus_decode
  333. PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  334. target_link_libraries(test_opus_decode PRIVATE opus)
  335. if(OPUS_FIXED_POINT)
  336. target_compile_definitions(test_opus_decode PRIVATE DISABLE_FLOAT_API)
  337. endif()
  338. add_test(test_opus_decode test_opus_decode)
  339. add_executable(test_opus_padding ${test_opus_padding_sources})
  340. target_include_directories(test_opus_padding
  341. PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  342. target_link_libraries(test_opus_padding PRIVATE opus)
  343. add_test(test_opus_padding test_opus_padding)
  344. if(NOT BUILD_SHARED_LIBS)
  345. # disable tests that depends on private API when building shared lib
  346. add_executable(test_opus_api ${test_opus_api_sources})
  347. target_include_directories(test_opus_api
  348. PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt)
  349. target_link_libraries(test_opus_api PRIVATE opus)
  350. if(OPUS_FIXED_POINT)
  351. target_compile_definitions(test_opus_api PRIVATE DISABLE_FLOAT_API)
  352. endif()
  353. add_test(test_opus_api test_opus_api)
  354. add_executable(test_opus_encode ${test_opus_encode_sources})
  355. target_include_directories(test_opus_encode
  356. PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt)
  357. target_link_libraries(test_opus_encode PRIVATE opus)
  358. add_test(test_opus_encode test_opus_encode)
  359. endif()
  360. endif()