2
0

meson.build 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. project('libsrtp2', 'c', version: '2.4.0',
  2. meson_version: '>= 0.52.0',
  3. default_options: ['buildtype=debugoptimized'])
  4. soversion = 1
  5. cc = meson.get_compiler('c')
  6. host_system = host_machine.system()
  7. srtp2_deps = []
  8. syslibs = []
  9. if host_system == 'windows'
  10. syslibs += [cc.find_library('ws2_32')] # for socket
  11. endif
  12. cdata = configuration_data()
  13. cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
  14. cdata.set_quoted('PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), meson.project_version()))
  15. check_headers = [
  16. 'arpa/inet.h',
  17. 'byteswap.h',
  18. 'inttypes.h',
  19. 'machine/types.h',
  20. 'netinet/in.h',
  21. 'stdint.h',
  22. 'stdlib.h',
  23. 'sys/int_types.h',
  24. 'sys/socket.h',
  25. 'sys/types.h',
  26. 'sys/uio.h',
  27. 'unistd.h',
  28. ]
  29. if host_system == 'windows'
  30. check_headers += ['windows.h', 'winsock2.h']
  31. endif
  32. foreach h : check_headers
  33. if cc.has_header(h)
  34. cdata.set('HAVE_' + h.to_upper().underscorify(), true)
  35. endif
  36. endforeach
  37. check_functions = [
  38. 'sigaction',
  39. 'inet_aton',
  40. 'usleep',
  41. 'socket',
  42. ]
  43. foreach f : check_functions
  44. if cc.has_function(f, dependencies: syslibs)
  45. cdata.set('HAVE_' + f.to_upper().underscorify(), true)
  46. endif
  47. endforeach
  48. if host_machine.endian() == 'big'
  49. cdata.set('WORDS_BIGENDIAN', true)
  50. endif
  51. # This follows the checks in configure.ac, but is it up-to-date ?!
  52. if host_machine.cpu_family() in ['x86', 'x86_64']
  53. cdata.set('CPU_CISC', true, description: 'Building for a CISC machine (e.g. Intel)')
  54. cdata.set('HAVE_X86', true, description: 'Use x86 inlined assembly code')
  55. else
  56. cdata.set('CPU_RISC', true, description: 'Building for a RISC machine (assume slow byte access)')
  57. endif
  58. # Pretty much all supported platforms have stdint.h nowadays
  59. assert(cc.has_header('stdint.h'), 'stdint.h not available!')
  60. # we'll just assume these types are available via stdint.h
  61. foreach type : ['int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'uint64_t']
  62. cdata.set('HAVE_' + type.to_upper().underscorify(), true)
  63. endforeach
  64. size_t_prefix = '''
  65. #ifdef _WIN32
  66. #include <crtdefs.h>
  67. #endif
  68. #include <sys/types.h>
  69. '''
  70. if not cc.has_type('size_t', prefix: size_t_prefix)
  71. cdata.set('size_t', 'unsigned int')
  72. endif
  73. # check type availability and size
  74. foreach type : ['unsigned long', 'unsigned long long']
  75. if cc.has_type(type)
  76. cdata.set('HAVE_' + type.to_upper().underscorify(), true)
  77. cdata.set('SIZEOF_' + type.to_upper().underscorify(), cc.sizeof(type))
  78. endif
  79. endforeach
  80. if not cc.compiles('inline void func(); void func() { } int main() { func(); return 0; }', name: 'inline keyword check')
  81. if cc.compiles('__inline void func(); void func() { } int main() { func(); return 0; }', name: '__inline keyword check')
  82. cdata.set('inline', '__inline')
  83. else
  84. cdata.set('inline', '')
  85. endif
  86. endif
  87. if get_option('log-stdout')
  88. cdata.set('ERR_REPORTING_STDOUT', true)
  89. endif
  90. if get_option('log-file') != ''
  91. cdata.set('ERR_REPORTING_FILE', get_option('log-file'))
  92. endif
  93. if cdata.has('ERR_REPORTING_STDOUT') and cdata.has('ERR_REPORTING_FILE')
  94. error('The log-stdout and log-file options are mutually exclusive!')
  95. endif
  96. if get_option('debug-logging')
  97. cdata.set('ENABLE_DEBUG_LOGGING', true)
  98. endif
  99. use_openssl = false
  100. use_nss = false
  101. crypto_library = get_option('crypto-library')
  102. if crypto_library == 'openssl'
  103. openssl_dep = dependency('openssl', version: '>= 1.0.1', required: true)
  104. srtp2_deps += [openssl_dep]
  105. cdata.set('GCM', true)
  106. cdata.set('OPENSSL', true)
  107. cdata.set('USE_EXTERNAL_CRYPTO', true)
  108. use_openssl = true
  109. # NOTE: This is not available in upstream OpenSSL yet. It's only in 'certain'
  110. # forks of OpenSSL: https://github.com/cisco/libsrtp/issues/458
  111. if (
  112. openssl_dep.type_name() != 'internal' and
  113. not get_option('crypto-library-kdf').disabled() and
  114. cc.has_function('kdf_srtp', dependencies: openssl_dep)
  115. )
  116. cdata.set('OPENSSL_KDF', true)
  117. elif get_option('crypto-library-kdf').enabled()
  118. error('KDF support has been enabled, but OpenSSL does not provide it')
  119. endif
  120. elif crypto_library == 'nss'
  121. nss_dep = dependency('nss', version: '>= 1.0.1', required: true)
  122. srtp2_deps += [nss_dep]
  123. cdata.set('GCM', true)
  124. cdata.set('NSS', true)
  125. cdata.set('USE_EXTERNAL_CRYPTO', true)
  126. use_nss = true
  127. # TODO(RLB): Use NSS for KDF
  128. if get_option('crypto-library-kdf').enabled()
  129. error('KDF support has not been implemented for NSS')
  130. endif
  131. endif
  132. configure_file(output: 'config.h', configuration: cdata)
  133. add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
  134. if get_option('buildtype') != 'plain'
  135. w_args = ['-Wstrict-prototypes']
  136. add_project_arguments(cc.get_supported_arguments(w_args), language: 'c')
  137. endif
  138. if get_option('optimization') not in ['0', 'g', 's']
  139. # -fexpensive-optimizations set already by default for -O2, -O3
  140. o_args = ['-funroll-loops']
  141. add_project_arguments(cc.get_supported_arguments(o_args), language: 'c')
  142. endif
  143. sources = files(
  144. 'srtp/srtp.c',
  145. )
  146. ciphers_sources = files(
  147. 'crypto/cipher/cipher.c',
  148. 'crypto/cipher/cipher_test_cases.c',
  149. 'crypto/cipher/null_cipher.c',
  150. )
  151. if use_openssl
  152. ciphers_sources += files(
  153. 'crypto/cipher/aes_icm_ossl.c',
  154. 'crypto/cipher/aes_gcm_ossl.c',
  155. )
  156. elif use_nss
  157. ciphers_sources += files(
  158. 'crypto/cipher/aes_icm_nss.c',
  159. 'crypto/cipher/aes_gcm_nss.c',
  160. )
  161. else
  162. ciphers_sources += files(
  163. 'crypto/cipher/aes.c',
  164. 'crypto/cipher/aes_icm.c',
  165. )
  166. endif
  167. hashes_sources = files(
  168. 'crypto/hash/auth.c',
  169. 'crypto/hash/auth_test_cases.c',
  170. 'crypto/hash/null_auth.c',
  171. )
  172. if use_openssl
  173. hashes_sources += files(
  174. 'crypto/hash/hmac_ossl.c',
  175. )
  176. elif use_nss
  177. hashes_sources += files(
  178. 'crypto/hash/hmac_nss.c',
  179. )
  180. else
  181. hashes_sources += files(
  182. 'crypto/hash/hmac.c',
  183. 'crypto/hash/sha1.c',
  184. )
  185. endif
  186. kernel_sources = files(
  187. 'crypto/kernel/alloc.c',
  188. 'crypto/kernel/crypto_kernel.c',
  189. 'crypto/kernel/err.c',
  190. 'crypto/kernel/key.c',
  191. )
  192. math_sources = files(
  193. 'crypto/math/datatypes.c',
  194. )
  195. replay_sources = files(
  196. 'crypto/replay/rdb.c',
  197. 'crypto/replay/rdbx.c',
  198. )
  199. public_headers = files(
  200. 'include/srtp.h',
  201. 'crypto/include/auth.h',
  202. 'crypto/include/cipher.h',
  203. 'crypto/include/crypto_types.h',
  204. )
  205. install_headers(public_headers, subdir : 'srtp2')
  206. config_incs = include_directories('.')
  207. crypto_incs = include_directories('crypto/include')
  208. srtp2_incs = include_directories('include')
  209. test_incs = include_directories('test')
  210. default_library = get_option('default_library')
  211. libsrtp2_static = static_library('srtp2', sources, ciphers_sources, hashes_sources,
  212. kernel_sources, math_sources, replay_sources,
  213. dependencies: [srtp2_deps, syslibs],
  214. include_directories: [crypto_incs, srtp2_incs],
  215. install: default_library != 'shared')
  216. if default_library != 'static'
  217. libsrtp2 = shared_library('srtp2',
  218. dependencies: [srtp2_deps, syslibs],
  219. soversion : soversion,
  220. vs_module_defs: 'srtp.def',
  221. link_whole: libsrtp2_static,
  222. install: true)
  223. else
  224. libsrtp2 = libsrtp2_static
  225. endif
  226. subdir('include/srtp2') # copies public_headers into the builddir and sets public_incs
  227. libsrtp2_dep = declare_dependency(link_with: libsrtp2,
  228. include_directories: public_incs)
  229. if not get_option('tests').disabled()
  230. # Tests use non-public API, and when building on Windows the only symbols we
  231. # export are those in srtp.def, so link to the static library in that case.
  232. if host_system == 'windows'
  233. libsrtp2_for_tests = libsrtp2_static
  234. else
  235. libsrtp2_for_tests = libsrtp2
  236. endif
  237. subdir('crypto/test')
  238. subdir('test')
  239. endif
  240. if not get_option('fuzzer').disabled()
  241. subdir('fuzzer')
  242. endif
  243. if not get_option('doc').disabled()
  244. subdir('doc')
  245. endif
  246. pkgconfig = import('pkgconfig')
  247. pkgconfig.generate(libsrtp2,
  248. filebase: meson.project_name(),
  249. name: meson.project_name(),
  250. version: meson.project_version(),
  251. description: 'Library for SRTP (Secure Realtime Transport Protocol)')