[cmake] expose some standard CMake options
[rtaudio.git] / CMakeLists.txt
1 # Set minimum CMake required version for this project.
2 cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
3
4 # Define a C++ project.
5 project(RtAudio LANGUAGES CXX)
6
7 # Check for Jack (any OS)
8 find_library(JACK_LIB jack)
9 find_package(PkgConfig)
10 pkg_check_modules(jack jack)
11 if(JACK_LIB OR jack_FOUND)
12   set(HAVE_JACK TRUE)
13 endif()
14
15 # Check for Pulse (any OS)
16 pkg_check_modules(pulse libpulse-simple)
17
18 # Check for known non-Linux unix-likes
19 if (CMAKE_SYSTEM_NAME MATCHES "kNetBSD.*|NetBSD.*")
20   message(STATUS "NetBSD detected, using OSS")
21   set(xBSD ON)
22 elseif(UNIX AND NOT APPLE)
23   set(LINUX ON)
24 endif()
25
26 # Necessary for Windows
27 if(MINGW)
28   set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
29 endif()
30
31 # Standard CMake options
32 option(BUILD_SHARED_LIBS "Build as shared library" ON)
33
34 if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
35   set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel")
36 endif()
37 if(WINDOWS)
38   set(CMAKE_DEBUG_POSTFIX d CACHE STRING "Postfix for debug version of library")
39 endif()
40
41 # Build Options
42 option(RTAUDIO_BUILD_PYTHON "Build PyRtAudio python bindings" OFF)
43 set(RTAUDIO_TARGETNAME_UNINSTALL "uninstall" CACHE STRING "Name of 'uninstall' build target")
44
45 # API Options
46 option(RTAUDIO_API_DS "Build DirectSound API" OFF)
47 option(RTAUDIO_API_ASIO "Build ASIO API" OFF)
48 option(RTAUDIO_API_WASAPI "Build WASAPI API" ${WIN32})
49 option(RTAUDIO_API_OSS "Build OSS4 API" ${xBSD})
50 option(RTAUDIO_API_ALSA "Build ALSA API" ${LINUX})
51 option(RTAUDIO_API_PULSE "Build PulseAudio API" ${pulse_FOUND})
52 option(RTAUDIO_API_JACK "Build JACK audio server API" ${HAVE_JACK})
53 option(RTAUDIO_API_CORE "Build CoreAudio API" ${APPLE})
54
55 # Check for functions
56 include(CheckFunctionExists)
57 check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
58 if (HAVE_GETTIMEOFDAY)
59     add_definitions(-DHAVE_GETTIMEOFDAY)
60 endif ()
61
62 # Add -Wall if possible
63 if (CMAKE_COMPILER_IS_GNUCXX)
64   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
65 endif (CMAKE_COMPILER_IS_GNUCXX)
66
67 # Add debug flags
68 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
69   add_definitions(-D__RTAUDIO_DEBUG__)
70   if (CMAKE_COMPILER_IS_GNUCXX)
71     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
72   endif (CMAKE_COMPILER_IS_GNUCXX)
73 endif ()
74
75 # Read libtool version info from configure.ac
76 set(R "m4_define\\(\\[lt_([a-z]+)\\], ([0-9]+)\\)")
77 file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGAC
78   REGEX ${R})
79 foreach(_S ${CONFIGAC})
80   string(REGEX REPLACE ${R} "\\1" k ${_S})
81   string(REGEX REPLACE ${R} "\\2" v ${_S})
82   set(SO_${k} ${v})
83 endforeach()
84 math(EXPR SO_current_minus_age "${SO_current} - ${SO_age}")
85 set(SO_VER "${SO_current_minus_age}")
86 set(FULL_VER "${SO_current_minus_age}.${SO_revision}.${SO_age}")
87
88 # Read package version info from configure.ac
89 set(R "AC_INIT\\(RtAudio, ([0-9\\.]+),.*\\)")
90 file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGAC
91   REGEX ${R})
92 string(REGEX REPLACE ${R} "\\1" PACKAGE_VERSION ${CONFIGAC})
93
94 # Init variables
95 set(rtaudio_SOURCES RtAudio.cpp RtAudio.h rtaudio_c.cpp rtaudio_c.h)
96 set(LINKLIBS)
97 set(PKGCONFIG_REQUIRES)
98 set(API_DEFS)
99 set(API_LIST)
100
101 # Tweak API-specific configuration.
102
103 # Jack
104 if (RTAUDIO_API_JACK AND jack_FOUND)
105   set(NEED_PTHREAD ON)
106   list(APPEND PKGCONFIG_REQUIRES "jack")
107   list(APPEND API_DEFS "-D__UNIX_JACK__")
108   list(APPEND API_LIST "jack")
109   if(jack_FOUND)
110     list(APPEND LINKLIBS ${jack_LIBRARIES})
111     list(APPEND INCDIRS ${jack_INCLUDEDIR})
112   else()
113     list(APPEND LINKLIBS ${JACK_LIB})
114   endif()
115 endif()
116
117 # ALSA
118 if (RTAUDIO_API_ALSA)
119   set(NEED_PTHREAD ON)
120   find_package(ALSA)
121   if (NOT ALSA_FOUND)
122     message(FATAL_ERROR "ALSA API requested but no ALSA dev libraries found")
123   endif()
124   list(APPEND INCDIRS ${ALSA_INCLUDE_DIR})
125   list(APPEND LINKLIBS ${ALSA_LIBRARY})
126   list(APPEND PKGCONFIG_REQUIRES "alsa")
127   list(APPEND API_DEFS "-D__LINUX_ALSA__")
128   list(APPEND API_LIST "alsa")
129 endif()
130
131 # OSS
132 if (RTAUDIO_OSS)
133   set(NEED_PTHREAD ON)
134   find_library(OSSAUDIO_LIB ossaudio)
135   if (OSSAUDIO_LIB)
136     list(APPEND LINKLIBS ossaudio)
137     # Note: not an error on some systems
138   endif()
139   list(APPEND API_DEFS "-D__LINUX_OSS__")
140   list(APPEND API_LIST "oss")
141 endif()
142
143 # Pulse
144 if (RTAUDIO_API_PULSE)
145   set(NEED_PTHREAD ON)
146   find_library(PULSE_LIB pulse)
147   find_library(PULSESIMPLE_LIB pulse-simple)
148   list(APPEND LINKLIBS ${PULSE_LIB} ${PULSESIMPLE_LIB})
149   list(APPEND PKGCONFIG_REQUIRES "libpulse-simple")
150   list(APPEND API_DEFS "-D__LINUX_PULSE__")
151   list(APPEND API_LIST "pulse")
152 endif()
153
154 # CoreAudio
155 if (RTAUDIO_API_CORE)
156   find_library(COREAUDIO_LIB CoreAudio)
157   find_library(COREFOUNDATION_LIB CoreFoundation)
158   list(APPEND LINKLIBS ${COREAUDIO_LIB} ${COREFOUNDATION_LIB})
159   list(APPEND API_DEFS "-D__MACOSX_CORE__")
160   list(APPEND API_LIST "core")
161 endif()
162
163 # ASIO
164 if (RTAUDIO_API_ASIO)
165   set(NEED_WIN32LIBS ON)
166   include_directories(include)
167   list(APPEND rtaudio_SOURCES
168     include/asio.cpp
169     include/asiodrivers.cpp
170     include/asiolist.cpp
171     include/iasiothiscallresolver.cpp)
172   list(APPEND API_DEFS "-D__WINDOWS_ASIO__")
173   list(APPEND API_LIST "asio")
174 endif()
175
176 # DSound
177 if (RTAUDIO_API_DS)
178   set(NEED_WIN32LIBS ON)
179   list(APPEND LINKLIBS dsound)
180   list(APPEND API_DEFS "-D__WINDOWS_DS__")
181   list(APPEND API_LIST "ds")
182 endif()
183
184 # WASAPI
185 if (RTAUDIO_API_WASAPI)
186   include_directories(include)
187   set(NEED_WIN32LIBS ON)
188   list(APPEND LINKLIBS ksuser mfplat mfuuid wmcodecdspuuid)
189   list(APPEND API_DEFS "-D__WINDOWS_WASAPI__")
190   list(APPEND API_LIST "wasapi")
191 endif()
192
193 # Windows libs
194 if (NEED_WIN32LIBS)
195   list(APPEND LINKLIBS winmm ole32)
196 endif()
197
198 # pthread
199 if (NEED_PTHREAD)
200   find_package(Threads REQUIRED
201     CMAKE_THREAD_PREFER_PTHREAD
202     THREADS_PREFER_PTHREAD_FLAG)
203   list(APPEND LINKLIBS Threads::Threads)
204 endif()
205
206 # Create library targets.
207 cmake_policy(SET CMP0042 OLD)
208 set(LIB_TARGETS)
209
210 add_library(rtaudio ${rtaudio_SOURCES})
211 list(APPEND LIB_TARGETS rtaudio)
212 # Add headers destination for install rule.
213 set_target_properties(rtaudio PROPERTIES PUBLIC_HEADER RtAudio.h
214   SOVERSION ${SO_VER}
215   VERSION ${FULL_VER})
216 # Set include paths, populate target interface.
217 target_include_directories(rtaudio PRIVATE
218   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
219   $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
220   ${INCDIRS})
221 # Set compile-time definitions
222 target_compile_definitions(rtaudio PRIVATE ${API_DEFS})
223 target_compile_definitions(rtaudio PRIVATE RTAUDIO_EXPORT)
224 target_link_libraries(rtaudio ${LINKLIBS})
225
226
227 # Set standard installation directories.
228 include(GNUInstallDirs)
229
230 # Subdirs
231 include(CTest)
232
233 if (BUILD_TESTING)
234   add_subdirectory(tests)
235 endif()
236
237 # Message
238 string(REPLACE ";" " " apilist "${API_LIST}")
239 message(STATUS "Compiling with support for: ${apilist}")
240
241 # PkgConfig file
242 string(REPLACE ";" " " req "${PKGCONFIG_REQUIRES}")
243 string(REPLACE ";" " " api "${API_DEFS}")
244 set(prefix ${CMAKE_INSTALL_PREFIX})
245 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rtaudio.pc.in" "rtaudio.pc" @ONLY)
246
247 # Add install rule.
248 install(TARGETS ${LIB_TARGETS}
249         EXPORT RtAudioTargets
250         LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
251         ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
252         RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
253         PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
254
255 # Store the package in the user registry.
256 export(PACKAGE RtAudio)
257
258 # Set installation path for CMake files.
259 set(RTAUDIO_CMAKE_DESTINATION share/rtaudio)
260
261 # Create CMake configuration export file.
262 if(NEED_PTHREAD)
263   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake "find_package(Threads REQUIRED)\n")
264 endif()
265
266 file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake "include(\${CMAKE_CURRENT_LIST_DIR}/RtAudioTargets.cmake)")
267
268 # Install CMake configuration export file.
269 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake
270         DESTINATION ${RTAUDIO_CMAKE_DESTINATION})
271
272 # Export library target (build-tree).
273 export(EXPORT RtAudioTargets
274        NAMESPACE RtAudio::)
275
276 # Export library target (install-tree).
277 install(EXPORT RtAudioTargets
278         DESTINATION ${RTAUDIO_CMAKE_DESTINATION}
279         NAMESPACE RtAudio::)
280
281 # Configure uninstall target.
282 configure_file(
283     "${CMAKE_CURRENT_SOURCE_DIR}/cmake/RtAudioConfigUninstall.cmake.in"
284     "${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfigUninstall.cmake" @ONLY)
285
286 # Create uninstall target.
287 add_custom_target(${RTAUDIO_TARGETNAME_UNINSTALL}
288     COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfigUninstall.cmake)
289
290 install(
291     FILES ${CMAKE_CURRENT_BINARY_DIR}/rtaudio.pc
292     DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)