[cmake] support previous RTAUDIO_BUILD_* variables
[rtaudio.git] / CMakeLists.txt
index 2856c5fc78774930a742a1dae28bb9848444fc38..b88963ff7c26ab940eab9041aa381dd59d7611d2 100644 (file)
@@ -1,12 +1,16 @@
-cmake_minimum_required(VERSION 2.8.10)
-project(RtAudio)
+# Set minimum CMake required version for this project.
+cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
 
-include(CTest)
-include(CheckFunctionExists)
+# Define a C++ project.
+project(RtAudio LANGUAGES CXX)
 
 # Check for Jack (any OS)
+find_library(JACK_LIB jack)
 find_package(PkgConfig)
 pkg_check_modules(jack jack)
+if(JACK_LIB OR jack_FOUND)
+  set(HAVE_JACK TRUE)
+endif()
 
 # Check for Pulse (any OS)
 pkg_check_modules(pulse libpulse-simple)
@@ -19,35 +23,110 @@ elseif(UNIX AND NOT APPLE)
   set(LINUX ON)
 endif()
 
-option(BUILD_PYTHON "Build PyRtAudio python bindings" OFF)
-option(RTAUDIO_DS "Build DirectSound API" OFF)
-option(RTAUDIO_ASIO "Build ASIO API" OFF)
-option(RTAUDIO_WASAPI "Build WASAPI API" ${WIN32})
-option(RTAUDIO_OSS "Build OSS4 API" ${xBSD})
-option(RTAUDIO_ALSA "Build ALSA API" ${LINUX})
-option(RTAUDIO_PULSE "Build PulseAudio API" ${pulse_FOUND})
-option(RTAUDIO_JACK "Build JACK audio server API" ${jack_FOUND})
-option(RTAUDIO_CORE "Build CoreAudio API" ${APPLE})
+# Necessary for Windows
+if(MINGW)
+  set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+endif()
 
-if (CMAKE_BUILD_TYPE STREQUAL "Debug")
-    add_definitions(-D__RTAUDIO_DEBUG__)
-endif ()
+# Standard CMake options
+option(BUILD_SHARED_LIBS "Build as shared library" ON)
 
-check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
+if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel")
+endif()
+if(WINDOWS)
+  set(CMAKE_DEBUG_POSTFIX d CACHE STRING "Postfix for debug version of library")
+endif()
+
+# Build Options
+option(RTAUDIO_BUILD_PYTHON "Build PyRtAudio python bindings" OFF)
+set(RTAUDIO_TARGETNAME_UNINSTALL "uninstall" CACHE STRING "Name of 'uninstall' build target")
 
+# API Options
+option(RTAUDIO_API_DS "Build DirectSound API" OFF)
+option(RTAUDIO_API_ASIO "Build ASIO API" OFF)
+option(RTAUDIO_API_WASAPI "Build WASAPI API" ${WIN32})
+option(RTAUDIO_API_OSS "Build OSS4 API" ${xBSD})
+option(RTAUDIO_API_ALSA "Build ALSA API" ${LINUX})
+option(RTAUDIO_API_PULSE "Build PulseAudio API" ${pulse_FOUND})
+option(RTAUDIO_API_JACK "Build JACK audio server API" ${HAVE_JACK})
+option(RTAUDIO_API_CORE "Build CoreAudio API" ${APPLE})
+
+# Check for functions
+include(CheckFunctionExists)
+check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
 if (HAVE_GETTIMEOFDAY)
     add_definitions(-DHAVE_GETTIMEOFDAY)
 endif ()
 
+# Add -Wall if possible
 if (CMAKE_COMPILER_IS_GNUCXX)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
 endif (CMAKE_COMPILER_IS_GNUCXX)
 
-set(rtaudio_SOURCES RtAudio.cpp rtaudio_c.cpp)
+# Add debug flags
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+  add_definitions(-D__RTAUDIO_DEBUG__)
+  if (CMAKE_COMPILER_IS_GNUCXX)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+  endif (CMAKE_COMPILER_IS_GNUCXX)
+endif ()
 
+# Read libtool version info from configure.ac
+set(R "m4_define\\(\\[lt_([a-z]+)\\], ([0-9]+)\\)")
+file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGAC
+  REGEX ${R})
+foreach(_S ${CONFIGAC})
+  string(REGEX REPLACE ${R} "\\1" k ${_S})
+  string(REGEX REPLACE ${R} "\\2" v ${_S})
+  set(SO_${k} ${v})
+endforeach()
+math(EXPR SO_current_minus_age "${SO_current} - ${SO_age}")
+set(SO_VER "${SO_current_minus_age}")
+set(FULL_VER "${SO_current_minus_age}.${SO_revision}.${SO_age}")
+
+# Read package version info from configure.ac
+set(R "AC_INIT\\(RtAudio, ([0-9\\.]+),.*\\)")
+file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGAC
+  REGEX ${R})
+string(REGEX REPLACE ${R} "\\1" PACKAGE_VERSION ${CONFIGAC})
+
+# Init variables
+set(rtaudio_SOURCES RtAudio.cpp RtAudio.h rtaudio_c.cpp rtaudio_c.h)
 set(LINKLIBS)
 set(PKGCONFIG_REQUIRES)
-set(PKGCONFIG_APIS)
+set(API_DEFS)
+set(API_LIST)
+
+# Tweak API-specific configuration.
+
+# Jack
+if (RTAUDIO_API_JACK AND jack_FOUND)
+  set(NEED_PTHREAD ON)
+  list(APPEND PKGCONFIG_REQUIRES "jack")
+  list(APPEND API_DEFS "-D__UNIX_JACK__")
+  list(APPEND API_LIST "jack")
+  if(jack_FOUND)
+    list(APPEND LINKLIBS ${jack_LIBRARIES})
+    list(APPEND INCDIRS ${jack_INCLUDEDIR})
+  else()
+    list(APPEND LINKLIBS ${JACK_LIB})
+  endif()
+endif()
+
+# ALSA
+if (RTAUDIO_API_ALSA)
+  set(NEED_PTHREAD ON)
+  find_package(ALSA)
+  if (NOT ALSA_FOUND)
+    message(FATAL_ERROR "ALSA API requested but no ALSA dev libraries found")
+  endif()
+  list(APPEND INCDIRS ${ALSA_INCLUDE_DIR})
+  list(APPEND LINKLIBS ${ALSA_LIBRARY})
+  list(APPEND PKGCONFIG_REQUIRES "alsa")
+  list(APPEND API_DEFS "-D__LINUX_ALSA__")
+  list(APPEND API_LIST "alsa")
+endif()
 
 # OSS
 if (RTAUDIO_OSS)
@@ -57,55 +136,32 @@ if (RTAUDIO_OSS)
     list(APPEND LINKLIBS ossaudio)
     # Note: not an error on some systems
   endif()
-  add_definitions(-D__LINUX_OSS__)
+  list(APPEND API_DEFS "-D__LINUX_OSS__")
+  list(APPEND API_LIST "oss")
 endif()
 
 # Pulse
-if (RTAUDIO_PULSE)
+if (RTAUDIO_API_PULSE)
   set(NEED_PTHREAD ON)
   find_library(PULSE_LIB pulse)
   find_library(PULSESIMPLE_LIB pulse-simple)
   list(APPEND LINKLIBS ${PULSE_LIB} ${PULSESIMPLE_LIB})
   list(APPEND PKGCONFIG_REQUIRES "libpulse-simple")
-  list(APPEND PKGCONFIG_APIS "__LINUX_PULSE__")
-  add_definitions(-D__LINUX_PULSE__)
-endif()
-
-# ALSA
-if (RTAUDIO_ALSA)
-  set(NEED_PTHREAD ON)
-  find_package(ALSA)
-  if (NOT ALSA_FOUND)
-    message(FATAL_ERROR "ALSA API requested but no ALSA dev libraries found")
-  endif()
-  include_directories(${ALSA_INCLUDE_DIR})
-  list(APPEND LINKLIBS ${ALSA_LIBRARY})
-  list(APPEND PKGCONFIG_REQUIRES "alsa")
-  list(APPEND PKGCONFIG_APIS "__LINUX_ALSA__")
-  add_definitions(-D__LINUX_ALSA__)
-endif()
-
-# JACK
-if (RTAUDIO_JACK)
-  set(NEED_PTHREAD ON)
-  find_library(JACK_LIB jack)
-  list(APPEND LINKLIBS ${JACK_LIB})
-  list(APPEND PKGCONFIG_REQUIRES "jack")
-  list(APPEND PKGCONFIG_APIS "__UNIX_JACK__")
-  add_definitions(-D__UNIX_JACK__)
+  list(APPEND API_DEFS "-D__LINUX_PULSE__")
+  list(APPEND API_LIST "pulse")
 endif()
 
 # CoreAudio
-if (RTAUDIO_CORE)
+if (RTAUDIO_API_CORE)
   find_library(COREAUDIO_LIB CoreAudio)
   find_library(COREFOUNDATION_LIB CoreFoundation)
   list(APPEND LINKLIBS ${COREAUDIO_LIB} ${COREFOUNDATION_LIB})
-  list(APPEND PKGCONFIG_APIS "__MACOSX_CORE__")
-  add_definitions(-D__MACOSX_CORE__)
+  list(APPEND API_DEFS "-D__MACOSX_CORE__")
+  list(APPEND API_LIST "core")
 endif()
 
 # ASIO
-if (RTAUDIO_ASIO)
+if (RTAUDIO_API_ASIO)
   set(NEED_WIN32LIBS ON)
   include_directories(include)
   list(APPEND rtaudio_SOURCES
@@ -113,33 +169,27 @@ if (RTAUDIO_ASIO)
     include/asiodrivers.cpp
     include/asiolist.cpp
     include/iasiothiscallresolver.cpp)
-  add_definitions(-D__WINDOWS_ASIO__)
-  list(APPEND PKGCONFIG_APIS "__WINDOWS_ASIO__")
+  list(APPEND API_DEFS "-D__WINDOWS_ASIO__")
+  list(APPEND API_LIST "asio")
 endif()
 
 # DSound
-if (RTAUDIO_DS)
+if (RTAUDIO_API_DS)
   set(NEED_WIN32LIBS ON)
-  add_definitions(-D__WINDOWS_DS__)
-  message(STATUS "Using Windows DirectSound")
   list(APPEND LINKLIBS dsound)
-  list(APPEND PKGCONFIG_APIS "__WINDOWS_DS__")
+  list(APPEND API_DEFS "-D__WINDOWS_DS__")
+  list(APPEND API_LIST "ds")
 endif()
 
 # WASAPI
-if (RTAUDIO_WASAPI)
+if (RTAUDIO_API_WASAPI)
+  include_directories(include)
   set(NEED_WIN32LIBS ON)
-  add_definitions(-D__WINDOWS_WASAPI__)
-  message(STATUS "Using Windows WASAPI")
-  list(APPEND LINKLIBS uuid ksuser)
-  list(APPEND PKGCONFIG_APIS "__WINDOWS_WASAPI__")
+  list(APPEND LINKLIBS ksuser mfplat mfuuid wmcodecdspuuid)
+  list(APPEND API_DEFS "-D__WINDOWS_WASAPI__")
+  list(APPEND API_LIST "wasapi")
 endif()
 
-cmake_policy(SET CMP0042 OLD)
-set(PACKAGE_VERSION 5.0.0)
-add_library(rtaudio SHARED ${rtaudio_SOURCES})
-add_library(rtaudio_static STATIC ${rtaudio_SOURCES})
-
 # Windows libs
 if (NEED_WIN32LIBS)
   list(APPEND LINKLIBS winmm ole32)
@@ -153,29 +203,112 @@ if (NEED_PTHREAD)
   list(APPEND LINKLIBS Threads::Threads)
 endif()
 
+# Create library targets.
+cmake_policy(SET CMP0042 OLD)
+set(LIB_TARGETS)
+
+# Use RTAUDIO_BUILD_SHARED_LIBS / RTAUDIO_BUILD_STATIC_LIBS if they
+# are defined, otherwise default to standard BUILD_SHARED_LIBS.
+if (DEFINED RTAUDIO_BUILD_SHARED_LIBS)
+  if (RTAUDIO_BUILD_SHARED_LIBS)
+    add_library(rtaudio SHARED ${rtaudio_SOURCES})
+  else()
+    add_library(rtaudio STATIC ${rtaudio_SOURCES})
+  endif()
+elseif (DEFINED RTAUDIO_BUILD_STATIC_LIBS)
+  if (RTAUDIO_BUILD_STATIC_LIBS)
+    add_library(rtaudio STATIC ${rtaudio_SOURCES})
+  else()
+    add_library(rtaudio SHARED ${rtaudio_SOURCES})
+  endif()
+else()
+  add_library(rtaudio ${rtaudio_SOURCES})
+endif()
+list(APPEND LIB_TARGETS rtaudio)
+
+# Add headers destination for install rule.
+set_target_properties(rtaudio PROPERTIES PUBLIC_HEADER RtAudio.h
+  SOVERSION ${SO_VER}
+  VERSION ${FULL_VER})
+
+# Set include paths, populate target interface.
+target_include_directories(rtaudio PRIVATE
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+  ${INCDIRS})
+
+# Set compile-time definitions
+target_compile_definitions(rtaudio PRIVATE ${API_DEFS})
+target_compile_definitions(rtaudio PRIVATE RTAUDIO_EXPORT)
 target_link_libraries(rtaudio ${LINKLIBS})
 
-if (BUILD_TESTING)
-    add_subdirectory(tests)
-endif (BUILD_TESTING)
 
+# Set standard installation directories.
+include(GNUInstallDirs)
+
+# Subdirs
+include(CTest)
+
+if (NOT DEFINED RTAUDIO_BUILD_TESTING OR RTAUDIO_BUILD_TESTING STREQUAL "")
+  set(RTAUDIO_BUILD_TESTING ${BUILD_TESTING})
+endif()
+if (RTAUDIO_BUILD_TESTING)
+  add_subdirectory(tests)
+endif()
+
+# Message
+string(REPLACE ";" " " apilist "${API_LIST}")
+message(STATUS "Compiling with support for: ${apilist}")
+
+# PkgConfig file
 string(REPLACE ";" " " req "${PKGCONFIG_REQUIRES}")
-string(REPLACE ";" " -D" api "${PKGCONFIG_APIS}")
-string(PREPEND api "-D")
-configure_file("rtaudio.pc.in" "rtaudio.pc" @ONLY)
+string(REPLACE ";" " " api "${API_DEFS}")
+set(prefix ${CMAKE_INSTALL_PREFIX})
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rtaudio.pc.in" "rtaudio.pc" @ONLY)
 
-install(TARGETS rtaudio
-      LIBRARY DESTINATION lib
-      ARCHIVE DESTINATION lib
-      RUNTIME DESTINATION bin)
+# Add install rule.
+install(TARGETS ${LIB_TARGETS}
+        EXPORT RtAudioTargets
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 
-install(TARGETS rtaudio_static
-      ARCHIVE DESTINATION lib)
+# Store the package in the user registry.
+export(PACKAGE RtAudio)
 
-install(
-    FILES RtAudio.h
-    DESTINATION include)
+# Set installation path for CMake files.
+set(RTAUDIO_CMAKE_DESTINATION share/rtaudio)
+
+# Create CMake configuration export file.
+if(NEED_PTHREAD)
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake "find_package(Threads REQUIRED)\n")
+endif()
+
+file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake "include(\${CMAKE_CURRENT_LIST_DIR}/RtAudioTargets.cmake)")
+
+# Install CMake configuration export file.
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfig.cmake
+        DESTINATION ${RTAUDIO_CMAKE_DESTINATION})
+
+# Export library target (build-tree).
+export(EXPORT RtAudioTargets
+       NAMESPACE RtAudio::)
+
+# Export library target (install-tree).
+install(EXPORT RtAudioTargets
+        DESTINATION ${RTAUDIO_CMAKE_DESTINATION}
+        NAMESPACE RtAudio::)
+
+# Configure uninstall target.
+configure_file(
+    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/RtAudioConfigUninstall.cmake.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfigUninstall.cmake" @ONLY)
+
+# Create uninstall target.
+add_custom_target(${RTAUDIO_TARGETNAME_UNINSTALL}
+    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/RtAudioConfigUninstall.cmake)
 
 install(
     FILES ${CMAKE_CURRENT_BINARY_DIR}/rtaudio.pc
-    DESTINATION lib/pkgconfig)
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)