CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. cmake_minimum_required(VERSION 2.8.12)
  2. cmake_policy(SET CMP0077 NEW)
  3. project(bell)
  4. # Configurable options
  5. option(BELL_DISABLE_CODECS "Disable the entire audio codec wrapper" OFF)
  6. option(BELL_CODEC_AAC "Support libhelix-aac codec" ON)
  7. option(BELL_CODEC_MP3 "Support libhelix-mp3 codec" ON)
  8. option(BELL_CODEC_VORBIS "Support tremor Vorbis codec" ON)
  9. option(BELL_CODEC_ALAC "Support Apple ALAC codec" ON)
  10. option(BELL_CODEC_OPUS "Support Opus codec" ON)
  11. option(BELL_DISABLE_SINKS "Disable all built-in audio sink implementations" OFF)
  12. # These are default OFF, as they're OS-dependent (ESP32 sinks are always enabled - no external deps)
  13. option(BELL_SINK_ALSA "Enable ALSA audio sink" OFF)
  14. option(BELL_SINK_PORTAUDIO "Enable PortAudio sink" OFF)
  15. # cJSON wrapper
  16. option(BELL_ONLY_CJSON "Use only cJSON, not Nlohmann")
  17. set(BELL_EXTERNAL_CJSON "" CACHE STRING "External cJSON library target name, optional")
  18. # vorbis
  19. set(BELL_EXTERNAL_VORBIS "" CACHE STRING "External Vorbis library target name, optional")
  20. option(BELL_VORBIS_FLOAT "Use floating point Vorbis API" OFF)
  21. # fmt & regex
  22. option(BELL_DISABLE_FMT "Don't use std::fmt (saves space)" OFF)
  23. option(BELL_DISABLE_REGEX "Don't use std::regex (saves space)" OFF)
  24. # disable json tests
  25. set(JSON_BuildTests OFF CACHE INTERNAL "")
  26. # Backwards compatibility with deprecated options
  27. if(BELL_USE_ALSA)
  28. message(WARNING "Deprecated Bell options used, replace BELL_USE_ALSA with BELL_SINK_ALSA")
  29. set(BELL_SINK_ALSA ${BELL_USE_ALSA})
  30. endif()
  31. if(BELL_USE_PORTAUDIO)
  32. message(WARNING "Deprecated Bell options used, replace BELL_USE_PORTAUDIO with BELL_SINK_PORTAUDIO")
  33. set(BELL_SINK_PORTAUDIO ${BELL_USE_PORTAUDIO})
  34. endif()
  35. message(STATUS "Bell options:")
  36. message(STATUS " Disable all codecs: ${BELL_DISABLE_CODECS}")
  37. if(NOT BELL_DISABLE_CODECS)
  38. message(STATUS " - AAC audio codec: ${BELL_CODEC_AAC}")
  39. message(STATUS " - MP3 audio codec: ${BELL_CODEC_MP3}")
  40. message(STATUS " - Vorbis audio codec: ${BELL_CODEC_VORBIS}")
  41. message(STATUS " - Opus audio codec: ${BELL_CODEC_OPUS}")
  42. message(STATUS " - ALAC audio codec: ${BELL_CODEC_ALAC}")
  43. endif()
  44. message(STATUS " Disable built-in audio sinks: ${BELL_DISABLE_SINKS}")
  45. message(STATUS " Use Vorbis float version: ${BELL_VORBIS_FLOAT}")
  46. if(NOT BELL_DISABLE_SINKS)
  47. message(STATUS " - ALSA sink: ${BELL_SINK_ALSA}")
  48. message(STATUS " - PortAudio sink: ${BELL_SINK_PORTAUDIO}")
  49. endif()
  50. message(STATUS " Use cJSON only: ${BELL_ONLY_CJSON}")
  51. message(STATUS " Disable Fmt: ${BELL_DISABLE_FMT}")
  52. message(STATUS " Disable Regex: ${BELL_DISABLE_REGEX}")
  53. # Include nanoPB library
  54. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/external/nanopb/extra")
  55. find_package(Nanopb REQUIRED)
  56. message(${NANOPB_INCLUDE_DIRS})
  57. list(APPEND EXTRA_INCLUDES ${NANOPB_INCLUDE_DIRS})
  58. # CMake options
  59. set(CMAKE_CXX_STANDARD 20)
  60. set(CMAKE_CXX_STANDARD_REQUIRED 20)
  61. set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
  62. set(AUDIO_CODEC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/audio-codec")
  63. set(AUDIO_CONTAINERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/audio-containers")
  64. set(AUDIO_DSP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/audio-dsp")
  65. set(AUDIO_SINKS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/audio-sinks")
  66. set(IO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/io")
  67. set(PLATFORM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/platform")
  68. set(UTILITIES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/main/utilities")
  69. add_definitions("-DUSE_DEFAULT_STDLIB=1")
  70. # Main library sources
  71. file(GLOB SOURCES
  72. "external/nanopb/*.c"
  73. "main/utilities/*.cpp" "main/utilities/*.c"
  74. "main/io/*.cpp" "main/io/*.c"
  75. )
  76. list(REMOVE_ITEM SOURCES "${IO_DIR}/BellTar.cpp" "${IO_DIR}/BellHTTPServer.cpp")
  77. list(APPEND EXTRA_INCLUDES "main/audio-codec/include")
  78. list(APPEND EXTRA_INCLUDES "main/audio-dsp/include")
  79. list(APPEND EXTRA_INCLUDES "main/audio-sinks/include")
  80. list(APPEND EXTRA_INCLUDES "main/io/include")
  81. list(APPEND EXTRA_INCLUDES "main/utilities/include")
  82. list(APPEND EXTRA_INCLUDES "main/platform")
  83. # Add platform specific sources
  84. if(ESP_PLATFORM)
  85. file(GLOB ESP_PLATFORM_SOURCES "main/platform/esp/*.cpp" "main/platform/esp/*.c" "main/asm/biquad_f32_ae32.S")
  86. list(APPEND SOURCES ${ESP_PLATFORM_SOURCES})
  87. endif()
  88. if(APPLE)
  89. file(GLOB APPLE_PLATFORM_SOURCES "main/platform/apple/*.cpp" "main/platform/apple/*.c")
  90. list(APPEND SOURCES ${APPLE_PLATFORM_SOURCES})
  91. list(APPEND EXTRA_INCLUDES "/usr/local/opt/mbedtls@3/include")
  92. endif()
  93. if(UNIX AND NOT APPLE)
  94. file(GLOB LINUX_PLATFORM_SOURCES "main/platform/linux/*.cpp" "main/platform/linux/*.c")
  95. list(APPEND SOURCES ${LINUX_PLATFORM_SOURCES})
  96. endif()
  97. if(WIN32)
  98. file(GLOB WIN32_PLATFORM_SOURCES "main/platform/win32/*.cpp" "main/platform/win32/*.c")
  99. list(APPEND SOURCES ${WIN32_PLATFORM_SOURCES})
  100. list(APPEND EXTRA_INCLUDES "main/platform/win32")
  101. endif()
  102. # A hack to make Opus keep quiet
  103. function(message)
  104. if(NOT MESSAGE_QUIET)
  105. _message(${ARGN})
  106. endif()
  107. endfunction()
  108. if(ESP_PLATFORM)
  109. list(APPEND EXTRA_LIBS idf::mdns idf::mbedtls idf::pthread idf::driver idf::lwip)
  110. add_definitions(-Wunused-const-variable -Wchar-subscripts -Wunused-label -Wmaybe-uninitialized -Wmisleading-indentation -Wno-stringop-overflow -Wno-error=format -Wno-format -Wno-stringop-overread -Wno-stringop-overflow)
  111. else()
  112. find_package(Threads REQUIRED)
  113. find_package(MbedTLS REQUIRED)
  114. list(APPEND EXTRA_INCLUDES ${MBEDTLS_INCLUDE_DIRS})
  115. set(THREADS_PREFER_PTHREAD_FLAG ON)
  116. list(APPEND EXTRA_LIBS ${MBEDTLS_LIBRARIES} Threads::Threads)
  117. if(MSVC)
  118. add_compile_definitions(NOMINMAX _CRT_SECURE_NO_WARNINGS _USE_MATH_DEFINES)
  119. add_definitions(/wd4068 /wd4244 /wd4018 /wd4101 /wd4102 /wd4142)
  120. endif()
  121. endif()
  122. if(NOT BELL_DISABLE_CODECS)
  123. file(GLOB EXTRA_SOURCES "main/audio-containers/*.cpp" "main/audio-codec/*.cpp" "main/audio-codec/*.c" "main/audio-dsp/*.cpp" "main/audio-dsp/*.c")
  124. list(APPEND SOURCES "${EXTRA_SOURCES}")
  125. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/DecoderGlobals.cpp")
  126. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/BaseCodec.cpp")
  127. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/AudioCodecs.cpp")
  128. list(APPEND EXTRA_INCLUDES "main/audio-containers/include")
  129. # AAC-LC codec
  130. if(BELL_CODEC_AAC)
  131. file(GLOB LIBHELIX_AAC_SOURCES "external/libhelix-aac/*.c")
  132. list(APPEND LIBHELIX_SOURCES ${LIBHELIX_AAC_SOURCES})
  133. list(APPEND EXTRA_INCLUDES "external/libhelix-aac")
  134. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/AACDecoder.cpp")
  135. list(APPEND CODEC_FLAGS "-DBELL_CODEC_AAC")
  136. endif()
  137. # MP3 codec
  138. if(BELL_CODEC_MP3)
  139. file(GLOB LIBHELIX_MP3_SOURCES "external/libhelix-mp3/*.c")
  140. list(APPEND LIBHELIX_SOURCES ${LIBHELIX_MP3_SOURCES})
  141. list(APPEND EXTRA_INCLUDES "external/libhelix-mp3")
  142. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/MP3Decoder.cpp")
  143. list(APPEND CODEC_FLAGS "-DBELL_CODEC_MP3")
  144. endif()
  145. # MP3 codec
  146. # if(BELL_CODEC_ALAC)
  147. # file(GLOB ALAC_SOURCES "external/alac/*.c" "external/alac/*.cpp")
  148. # list(APPEND ALAC_SOURCES ${ALAC_SOURCES})
  149. # list(APPEND EXTRA_INCLUDES "external/alac")
  150. # # list(APPEND SOURCES "${AUDIO_DIR}/codec/ALACDecoder.cpp")
  151. # list(APPEND CODEC_FLAGS "-DBELL_CODEC_ALAC")
  152. # endif()
  153. # libhelix Cygwin workaround
  154. if(CYGWIN)
  155. # Both Cygwin and ESP are Unix-like so this seems to work (or, at least, compile)
  156. set_source_files_properties("${AUDIO_CODEC_DIR}/DecoderGlobals.cpp" ${LIBHELIX_SOURCES} PROPERTIES COMPILE_FLAGS "-DESP_PLATFORM")
  157. endif()
  158. list(APPEND SOURCES ${LIBHELIX_SOURCES})
  159. list(APPEND SOURCES ${ALAC_SOURCES})
  160. # Vorbis codec
  161. if(BELL_CODEC_VORBIS)
  162. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/VorbisDecoder.cpp")
  163. list(APPEND CODEC_FLAGS "-DBELL_CODEC_VORBIS")
  164. endif()
  165. # Opus codec
  166. if(BELL_CODEC_OPUS)
  167. set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF CACHE BOOL "")
  168. set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF)
  169. set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF CACHE BOOL "")
  170. set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF)
  171. set(MESSAGE_QUIET ON)
  172. add_subdirectory("external/opus")
  173. unset(MESSAGE_QUIET)
  174. target_compile_options(opus PRIVATE "-O3")
  175. list(APPEND EXTRA_LIBS Opus::opus)
  176. list(APPEND SOURCES "${AUDIO_CODEC_DIR}/OPUSDecoder.cpp")
  177. list(APPEND CODEC_FLAGS -DBELL_CODEC_OPUS)
  178. endif()
  179. # Enable global codecs
  180. string(REPLACE ";" " " CODEC_FLAGS "${CODEC_FLAGS}")
  181. set_source_files_properties("${AUDIO_CODEC_DIR}/AudioCodecs.cpp" PROPERTIES COMPILE_FLAGS "${CODEC_FLAGS}")
  182. else()
  183. list(REMOVE_ITEM SOURCES "${IO_DIR}/EncodedAudioStream.cpp")
  184. endif()
  185. if(NOT BELL_EXTERNAL_VORBIS STREQUAL "")
  186. message(STATUS "Using external Vorbis codec ${BELL_EXTERNAL_VORBIS}")
  187. list(APPEND EXTRA_LIBS ${BELL_EXTERNAL_VORBIS})
  188. else()
  189. file(GLOB TREMOR_SOURCES "external/tremor/*.c")
  190. list(REMOVE_ITEM TREMOR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/tremor/ivorbisfile_example.c")
  191. list(APPEND SOURCES ${TREMOR_SOURCES})
  192. list(APPEND EXTRA_INCLUDES "external/tremor")
  193. endif()
  194. if(NOT BELL_DISABLE_SINKS)
  195. set(PLATFORM "unix")
  196. if(ESP_PLATFORM)
  197. set(PLATFORM "esp")
  198. endif()
  199. # Add all built-in audio sinks
  200. file(GLOB SINK_SOURCES "${AUDIO_SINKS_DIR}/${PLATFORM}/*.cpp" "${AUDIO_SINKS_DIR}/${PLATFORM}/*.c")
  201. list(APPEND EXTRA_INCLUDES "main/audio-sinks/include/${PLATFORM}")
  202. # Find ALSA if required, else remove the sink
  203. if(BELL_SINK_ALSA)
  204. find_package(ALSA REQUIRED)
  205. list(APPEND EXTRA_INCLUDES ${ALSA_INCLUDE_DIRS})
  206. list(APPEND EXTRA_LIBS ${ALSA_LIBRARIES})
  207. else()
  208. list(REMOVE_ITEM SINK_SOURCES "${AUDIO_SINKS_DIR}/unix/ALSAAudioSink.cpp")
  209. endif()
  210. # Find PortAudio if required, else remove the sink
  211. if(BELL_SINK_PORTAUDIO)
  212. find_package(Portaudio REQUIRED)
  213. list(APPEND EXTRA_INCLUDES ${PORTAUDIO_INCLUDE_DIRS})
  214. list(APPEND EXTRA_LIBS ${PORTAUDIO_LIBRARIES})
  215. else()
  216. list(REMOVE_ITEM SINK_SOURCES "${AUDIO_SINKS_DIR}/unix/PortAudioSink.cpp")
  217. endif()
  218. list(APPEND SOURCES ${SINK_SOURCES})
  219. endif()
  220. if(NOT BELL_ONLY_CJSON)
  221. add_subdirectory(external/nlohmann_json)
  222. list(APPEND EXTRA_LIBS nlohmann_json::nlohmann_json)
  223. endif()
  224. if(BELL_EXTERNAL_CJSON)
  225. list(APPEND EXTRA_LIBS ${BELL_EXTERNAL_CJSON})
  226. else()
  227. list(APPEND SOURCES "external/cJSON/cJSON.c")
  228. list(APPEND EXTRA_INCLUDES "external/cJSON")
  229. endif()
  230. if (NOT BELL_DISABLE_FMT)
  231. list(APPEND EXTRA_INCLUDES "external/fmt/include")
  232. endif()
  233. if(WIN32 OR UNIX)
  234. list(APPEND SOURCES "external/mdnssvc/mdns.c" "external/mdnssvc/mdnsd.c")
  235. list(APPEND EXTRA_INCLUDES "external/mdnssvc")
  236. endif()
  237. # file(GLOB CIVET_SRC "external/civetweb/*.c" "external/civetweb/*.inl" "external/civetweb/*.cpp")
  238. # list(APPEND SOURCES ${CIVET_SRC})
  239. # list(APPEND EXTRA_INCLUDES "external/civetweb/include")
  240. add_library(bell STATIC ${SOURCES})
  241. # Add Apple Bonjour compatibility library for Linux
  242. if(UNIX AND NOT APPLE)
  243. if (BELL_DISABLE_AVAHI)
  244. add_compile_definitions(BELL_DISABLE_AVAHI)
  245. else()
  246. list(APPEND EXTRA_LIBS avahi-client avahi-common)
  247. endif()
  248. endif()
  249. # PUBLIC to propagate esp-idf includes to bell dependents
  250. target_link_libraries(bell PUBLIC ${EXTRA_LIBS})
  251. target_include_directories(bell PUBLIC ${EXTRA_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
  252. target_compile_definitions(bell PUBLIC PB_ENABLE_MALLOC FMT_HEADER_ONLY)
  253. if(BELL_DISABLE_CODECS)
  254. target_compile_definitions(bell PUBLIC BELL_DISABLE_CODECS)
  255. endif()
  256. if(BELL_VORBIS_FLOAT)
  257. target_compile_definitions(bell PUBLIC BELL_VORBIS_FLOAT)
  258. endif()
  259. if(BELL_DISABLE_FMT)
  260. target_compile_definitions(bell PUBLIC BELL_DISABLE_FMT)
  261. endif()
  262. if(BELL_DISABLE_REGEX)
  263. target_compile_definitions(bell PUBLIC BELL_DISABLE_REGEX)
  264. endif()
  265. if(BELL_ONLY_CJSON)
  266. target_compile_definitions(bell PUBLIC BELL_ONLY_CJSON)
  267. endif()
  268. if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "SunOS")
  269. target_compile_definitions(bell PUBLIC PB_NO_STATIC_ASSERT)
  270. endif()