From 9802c1285962f4bb187ee280a21908dc134083d0 Mon Sep 17 00:00:00 2001 From: Stephen Sinclair Date: Sat, 14 Jul 2018 18:46:12 -0400 Subject: [PATCH] cmake: make CMakeLists.txt more similar to RtMidi's --- CMakeLists.txt | 286 +++++++++++++++++++------- cmake/RtAudioConfigUninstall.cmake.in | 21 ++ tests/CMakeLists.txt | 16 +- 3 files changed, 236 insertions(+), 87 deletions(-) create mode 100644 cmake/RtAudioConfigUninstall.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 2856c5f..80e9b3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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.0 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,104 @@ elseif(UNIX AND NOT APPLE) set(LINUX ON) endif() +# Necessary for Windows +if(WIN32) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + set(CMAKE_DEBUG_POSTFIX "d") +endif() + +# Build Options +option(BUILD_SHARED_LIBS "Compile library shared lib." TRUE) +option(BUILD_STATIC_LIBS "Compile library static lib." TRUE) +option(BUILD_TESTING "Compile test programs." TRUE) 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}) +set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (Release,Debug)") -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - add_definitions(-D__RTAUDIO_DEBUG__) -endif () +# 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) 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 +130,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 +163,26 @@ 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) 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 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 +196,112 @@ if (NEED_PTHREAD) list(APPEND LINKLIBS Threads::Threads) endif() -target_link_libraries(rtaudio ${LINKLIBS}) +# Create library targets. +cmake_policy(SET CMP0042 OLD) +set(LIB_TARGETS) +if(BUILD_SHARED_LIBS) + add_library(rtaudio SHARED ${rtaudio_SOURCES}) + 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 + $ + $ + ${INCDIRS}) + + # Set compile-time definitions + target_compile_definitions(rtaudio PRIVATE ${API_DEFS}) + + target_link_libraries(rtaudio ${LINKLIBS}) +endif() +if(BUILD_STATIC_LIBS) + add_library(rtaudio_static STATIC ${rtaudio_SOURCES}) + list(APPEND LIB_TARGETS rtaudio_static) + + # Add headers destination for install rule. + set_target_properties(rtaudio_static PROPERTIES PUBLIC_HEADER RtAudio.h + SOVERSION ${SO_VER} + VERSION ${FULL_VER}) + + # Set include paths, populate target interface. + target_include_directories(rtaudio_static PRIVATE + $ + $ + ${INCDIRS}) + + # Set compile-time definitions + target_compile_definitions(rtaudio_static PRIVATE ${API_DEFS}) + + target_link_libraries(rtaudio_static ${LINKLIBS}) +endif() + +# Set standard installation directories. +include(GNUInstallDirs) + +# Subdirs if (BUILD_TESTING) - add_subdirectory(tests) + include(CTest) + add_subdirectory(tests) endif (BUILD_TESTING) +# 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") +string(REPLACE ";" " " api "${API_DEFS}") configure_file("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. +if(WIN32) + set(RTAUDIO_CMAKE_DESTINATION cmake) +else() + set(RTAUDIO_CMAKE_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/RtAudio) +endif() + +# Create CMake configuration export file. +file(WRITE ${CMAKE_BINARY_DIR}/RtAudioConfig.cmake "include(\${CMAKE_CURRENT_LIST_DIR}/RtAudioTargets.cmake)") + +# Install CMake configuration export file. +install(FILES ${CMAKE_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_SOURCE_DIR}/cmake/RtAudioConfigUninstall.cmake.in" + "${CMAKE_BINARY_DIR}/RtAudioConfigUninstall.cmake" @ONLY) + +# Create uninstall target. +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/RtAudioConfigUninstall.cmake) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/rtaudio.pc - DESTINATION lib/pkgconfig) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/cmake/RtAudioConfigUninstall.cmake.in b/cmake/RtAudioConfigUninstall.cmake.in new file mode 100644 index 0000000..db894b3 --- /dev/null +++ b/cmake/RtAudioConfigUninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if(EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif(NOT "${rm_retval}" STREQUAL 0) + else(EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif(EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0fb028f..5c08f6d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,23 +3,25 @@ if (WIN32) include_directories(../include) endif (WIN32) +list(GET LIB_TARGETS 0 LIBRTAUDIO) + add_executable(audioprobe audioprobe.cpp) -target_link_libraries(audioprobe rtaudio_static ${LINKLIBS}) +target_link_libraries(audioprobe ${LIBRTAUDIO} ${LINKLIBS}) add_executable(playsaw playsaw.cpp) -target_link_libraries(playsaw rtaudio_static ${LINKLIBS}) +target_link_libraries(playsaw ${LIBRTAUDIO} ${LINKLIBS}) add_executable(playraw playraw.cpp) -target_link_libraries(playraw rtaudio_static ${LINKLIBS}) +target_link_libraries(playraw ${LIBRTAUDIO} ${LINKLIBS}) add_executable(record record.cpp) -target_link_libraries(record rtaudio_static ${LINKLIBS}) +target_link_libraries(record ${LIBRTAUDIO} ${LINKLIBS}) add_executable(duplex duplex.cpp) -target_link_libraries(duplex rtaudio_static ${LINKLIBS}) +target_link_libraries(duplex ${LIBRTAUDIO} ${LINKLIBS}) add_executable(testall testall.cpp) -target_link_libraries(testall rtaudio_static ${LINKLIBS}) +target_link_libraries(testall ${LIBRTAUDIO} ${LINKLIBS}) add_executable(teststops teststops.cpp) -target_link_libraries(teststops rtaudio_static ${LINKLIBS}) +target_link_libraries(teststops ${LIBRTAUDIO} ${LINKLIBS}) -- 2.30.2