OpusFunctions.cmake 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. if(__opus_functions)
  2. return()
  3. endif()
  4. set(__opus_functions INCLUDED)
  5. function(get_library_version OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR)
  6. file(STRINGS configure.ac opus_lt_current_string
  7. LIMIT_COUNT 1
  8. REGEX "OPUS_LT_CURRENT=")
  9. string(REGEX MATCH
  10. "OPUS_LT_CURRENT=([0-9]*)"
  11. _
  12. ${opus_lt_current_string})
  13. set(OPUS_LT_CURRENT ${CMAKE_MATCH_1})
  14. file(STRINGS configure.ac opus_lt_revision_string
  15. LIMIT_COUNT 1
  16. REGEX "OPUS_LT_REVISION=")
  17. string(REGEX MATCH
  18. "OPUS_LT_REVISION=([0-9]*)"
  19. _
  20. ${opus_lt_revision_string})
  21. set(OPUS_LT_REVISION ${CMAKE_MATCH_1})
  22. file(STRINGS configure.ac opus_lt_age_string
  23. LIMIT_COUNT 1
  24. REGEX "OPUS_LT_AGE=")
  25. string(REGEX MATCH
  26. "OPUS_LT_AGE=([0-9]*)"
  27. _
  28. ${opus_lt_age_string})
  29. set(OPUS_LT_AGE ${CMAKE_MATCH_1})
  30. math(EXPR OPUS_LIBRARY_VERSION_MAJOR "${OPUS_LT_CURRENT} - ${OPUS_LT_AGE}")
  31. set(OPUS_LIBRARY_VERSION_MINOR ${OPUS_LT_AGE})
  32. set(OPUS_LIBRARY_VERSION_PATCH ${OPUS_LT_REVISION})
  33. set(
  34. OPUS_LIBRARY_VERSION
  35. "${OPUS_LIBRARY_VERSION_MAJOR}.${OPUS_LIBRARY_VERSION_MINOR}.${OPUS_LIBRARY_VERSION_PATCH}"
  36. PARENT_SCOPE)
  37. set(OPUS_LIBRARY_VERSION_MAJOR ${OPUS_LIBRARY_VERSION_MAJOR} PARENT_SCOPE)
  38. endfunction()
  39. function(check_flag NAME FLAG)
  40. include(CheckCCompilerFlag)
  41. check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED)
  42. endfunction()
  43. include(CheckIncludeFile)
  44. # function to check if compiler supports SSE, SSE2, SSE4.1 and AVX if target
  45. # systems may not have SSE support then use OPUS_MAY_HAVE_SSE option if target
  46. # system is guaranteed to have SSE support then OPUS_PRESUME_SSE can be used to
  47. # skip SSE runtime check
  48. function(opus_detect_sse COMPILER_SUPPORT_SIMD)
  49. message(STATUS "Check SIMD support by compiler")
  50. check_include_file(xmmintrin.h HAVE_XMMINTRIN_H) # SSE1
  51. if(HAVE_XMMINTRIN_H)
  52. if(MSVC)
  53. # different arch options for 32 and 64 bit target for MSVC
  54. if(CMAKE_SIZEOF_VOID_P EQUAL 4)
  55. check_flag(SSE1 /arch:SSE)
  56. else()
  57. set(SSE1_SUPPORTED
  58. 1
  59. PARENT_SCOPE)
  60. endif()
  61. else()
  62. check_flag(SSE1 -msse)
  63. endif()
  64. else()
  65. set(SSE1_SUPPORTED
  66. 0
  67. PARENT_SCOPE)
  68. endif()
  69. check_include_file(emmintrin.h HAVE_EMMINTRIN_H) # SSE2
  70. if(HAVE_EMMINTRIN_H)
  71. if(MSVC)
  72. if(CMAKE_SIZEOF_VOID_P EQUAL 4)
  73. check_flag(SSE2 /arch:SSE2)
  74. else()
  75. set(SSE2_SUPPORTED
  76. 1
  77. PARENT_SCOPE)
  78. endif()
  79. else()
  80. check_flag(SSE2 -msse2)
  81. endif()
  82. else()
  83. set(SSE2_SUPPORTED
  84. 0
  85. PARENT_SCOPE)
  86. endif()
  87. check_include_file(smmintrin.h HAVE_SMMINTRIN_H) # SSE4.1
  88. if(HAVE_SMMINTRIN_H)
  89. if(MSVC)
  90. if(CMAKE_SIZEOF_VOID_P EQUAL 4)
  91. check_flag(SSE4_1 /arch:SSE2) # SSE2 and above
  92. else()
  93. set(SSE4_1_SUPPORTED
  94. 1
  95. PARENT_SCOPE)
  96. endif()
  97. else()
  98. check_flag(SSE4_1 -msse4.1)
  99. endif()
  100. else()
  101. set(SSE4_1_SUPPORTED
  102. 0
  103. PARENT_SCOPE)
  104. endif()
  105. check_include_file(immintrin.h HAVE_IMMINTRIN_H) # AVX
  106. if(HAVE_IMMINTRIN_H)
  107. if(MSVC)
  108. check_flag(AVX /arch:AVX)
  109. else()
  110. check_flag(AVX -mavx)
  111. endif()
  112. else()
  113. set(AVX_SUPPORTED
  114. 0
  115. PARENT_SCOPE)
  116. endif()
  117. if(SSE1_SUPPORTED OR SSE2_SUPPORTED OR SSE4_1_SUPPORTED OR AVX_SUPPORTED)
  118. set(COMPILER_SUPPORT_SIMD 1 PARENT_SCOPE)
  119. else()
  120. message(STATUS "No SIMD support in compiler")
  121. endif()
  122. endfunction()
  123. function(opus_detect_neon COMPILER_SUPPORT_NEON)
  124. if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
  125. message(STATUS "Check NEON support by compiler")
  126. check_include_file(arm_neon.h HAVE_ARM_NEON_H)
  127. if(HAVE_ARM_NEON_H)
  128. set(COMPILER_SUPPORT_NEON ${HAVE_ARM_NEON_H} PARENT_SCOPE)
  129. endif()
  130. endif()
  131. endfunction()
  132. function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION)
  133. set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
  134. if(OPUS_CPU_X86 OR OPUS_CPU_X64)
  135. if(MSVC)
  136. check_include_file(intrin.h HAVE_INTRIN_H)
  137. if(HAVE_INTRIN_H)
  138. # if intrin.h is available we assume __cpuid is there
  139. set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
  140. endif()
  141. else()
  142. include(CFeatureCheck)
  143. c_feature_check(CPU_INFO_BY_ASM)
  144. set(CPU_INFO_BY_ASM_SUPPORTED ${CPU_INFO_BY_ASM_SUPPORTED} PARENT_SCOPE)
  145. check_include_file(cpuid.h HAVE_CPUID_H)
  146. if(HAVE_CPUID_H)
  147. c_feature_check(CPU_INFO_BY_C)
  148. set(CPU_INFO_BY_C_SUPPORTED ${CPU_INFO_BY_C_SUPPORTED} PARENT_SCOPE)
  149. endif()
  150. if(CPU_INFO_BY_ASM_SUPPORTED OR CPU_INFO_BY_C_SUPPORTED)
  151. set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
  152. endif()
  153. endif()
  154. elseif(OPUS_CPU_ARM)
  155. # ARM cpu detection is implemented for Windows and anything
  156. # using a Linux kernel (such as Android).
  157. if (CMAKE_SYSTEM_NAME MATCHES "(Windows|Linux|Android)")
  158. set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
  159. endif ()
  160. else()
  161. set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
  162. endif()
  163. endfunction()
  164. function(add_sources_group target group)
  165. target_sources(${target} PRIVATE ${ARGN})
  166. source_group(${group} FILES ${ARGN})
  167. endfunction()
  168. function(get_opus_sources SOURCE_GROUP MAKE_FILE SOURCES)
  169. # read file, each item in list is one group
  170. file(STRINGS ${MAKE_FILE} opus_sources)
  171. # add wildcard for regex match
  172. string(CONCAT SOURCE_GROUP ${SOURCE_GROUP} ".*$")
  173. # find group
  174. foreach(val IN LISTS opus_sources)
  175. if(val MATCHES ${SOURCE_GROUP})
  176. list(LENGTH val list_length)
  177. if(${list_length} EQUAL 1)
  178. # for tests split by '=' and clean up the rest into a list
  179. string(FIND ${val} "=" index)
  180. math(EXPR index "${index} + 1")
  181. string(SUBSTRING ${val}
  182. ${index}
  183. -1
  184. sources)
  185. string(REPLACE " "
  186. ";"
  187. sources
  188. ${sources})
  189. else()
  190. # discard the group
  191. list(REMOVE_AT val 0)
  192. set(sources ${val})
  193. endif()
  194. break()
  195. endif()
  196. endforeach()
  197. list(LENGTH sources list_length)
  198. if(${list_length} LESS 1)
  199. message(
  200. FATAL_ERROR
  201. "No files parsed succesfully from ${SOURCE_GROUP} in ${MAKE_FILE}")
  202. endif()
  203. # remove trailing whitespaces
  204. set(list_var "")
  205. foreach(source ${sources})
  206. string(STRIP "${source}" source)
  207. list(APPEND list_var "${source}")
  208. endforeach()
  209. set(${SOURCES} ${list_var} PARENT_SCOPE)
  210. endfunction()