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