Skip to content

Commit

Permalink
3rdparty/portaudio: Updated to latest upstream version. (#11604)
Browse files Browse the repository at this point in the history
Up-to-date with revision 24c8d575e588d557d28f4011becb753421346860.  Resolves issues building with Visual Studio.

Enabled PortAudio when building with Visual Studio and clang-cl.

docs: Removed note about duplicate GUID symbols in PortAudio when built with MSVC.
  • Loading branch information
invertego authored Oct 8, 2023
1 parent 07b3bdd commit 963561c
Show file tree
Hide file tree
Showing 47 changed files with 5,453 additions and 694 deletions.
65 changes: 54 additions & 11 deletions 3rdparty/portaudio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,33 @@ else()
set(LIBRARY_BUILD_TYPE STATIC)
endif()

option(PA_WARNINGS_ARE_ERRORS "Turn compiler warnings into errors" OFF)
if(PA_WARNINGS_ARE_ERRORS)
if(MSVC)
add_compile_options(/WX
# "Grandfathered" warnings that existed before we started enforcement.
# Do *NOT* add warnings to this list. Instead, fix your code so that it doesn't produce the warning.
# TODO: fix the offending code so that we don't have to exclude specific warnings anymore.
/wd4244 # W2 conversion possible loss of data
/wd4267 # W3 conversion possible loss of data
/wd4996 # W3 unsafe/deprecated
)
else()
add_compile_options(-Werror
# "Grandfathered" warnings that existed before we started enforcement.
# Do *NOT* add warnings to this list. Instead, fix your code so that it doesn't produce the warning.
# TODO: fix the offending code so that we don't have to exclude specific warnings anymore.
-Wno-error=deprecated-declarations # https://github.com/PortAudio/portaudio/issues/213 https://github.com/PortAudio/portaudio/issues/641
-Wno-error=stringop-overflow
)
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
# Don't fail on older clang versions that don't recognize the latest warnings in the list above.
# Note that unrecognized warning options are not a fatal error on GCC, and in fact, GCC will choke on this option. Hence the conditional.
add_compile_options(-Wno-error=unknown-warning-option)
endif()
endif()
endif()

add_library(PortAudio
${LIBRARY_BUILD_TYPE}
src/common/pa_allocation.c
Expand Down Expand Up @@ -130,6 +157,8 @@ if(WIN32)
src/os/win/pa_win_hostapis.c
src/os/win/pa_win_util.c
src/os/win/pa_win_util.h
src/os/win/pa_win_version.c
src/os/win/pa_win_version.h
src/os/win/pa_win_waveformat.c
src/os/win/pa_win_wdmks_utils.h
src/os/win/pa_x86_plain_converters.h
Expand Down Expand Up @@ -278,17 +307,13 @@ elseif(UNIX)
target_include_directories(PortAudio PRIVATE src/hostapi/coreaudio)
set(PORTAUDIO_PUBLIC_HEADERS "${PORTAUDIO_PUBLIC_HEADERS}" include/pa_mac_core.h)

find_library(COREAUDIO_LIBRARY CoreAudio REQUIRED)
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox REQUIRED)
find_library(AUDIOUNIT_LIBRARY AudioUnit REQUIRED)
find_library(COREFOUNDATION_LIBRARY CoreFoundation REQUIRED)
find_library(CORESERVICES_LIBRARY CoreServices REQUIRED)
target_link_libraries(PortAudio PRIVATE
"${COREAUDIO_LIBRARY}"
"${AUDIOTOOLBOX_LIBRARY}"
"${AUDIOUNIT_LIBRARY}"
"${COREFOUNDATION_LIBRARY}"
"${CORESERVICES_LIBRARY}"
target_link_libraries(PortAudio
PRIVATE
-Wl,-framework,CoreAudio
-Wl,-framework,AudioToolbox
-Wl,-framework,AudioUnit
-Wl,-framework,CoreFoundation
-Wl,-framework,CoreServices
)
target_compile_definitions(PortAudio PUBLIC PA_USE_COREAUDIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_COREAUDIO=1")
Expand Down Expand Up @@ -340,6 +365,24 @@ elseif(UNIX)
target_compile_definitions(PortAudio PUBLIC PA_USE_AUDIOIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_AUDIOIO=1")
endif()

find_package(PulseAudio)
cmake_dependent_option(PA_USE_PULSEAUDIO "Enable support for PulseAudio general purpose sound server" ON PulseAudio_FOUND OFF)
if(PA_USE_PULSEAUDIO)
target_link_libraries(PortAudio PRIVATE PulseAudio::PulseAudio)
target_sources(PortAudio PRIVATE
src/hostapi/pulseaudio/pa_linux_pulseaudio_block.c
src/hostapi/pulseaudio/pa_linux_pulseaudio.c
src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c)

target_compile_definitions(PortAudio PUBLIC PA_USE_PULSEAUDIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_PULSEAUDIO=1")
set(PKGCONFIG_REQUIRES_PRIVATE "${PKGCONFIG_REQUIRES_PRIVATE} libpulse")

# needed for PortAudioConfig.cmake so `find_package(PortAudio)` works in downstream projects
install(FILES cmake/modules/FindPulseAudio.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/portaudio/modules")
endif()

endif()
endif()

Expand Down
7 changes: 4 additions & 3 deletions 3rdparty/portaudio/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PALIB = libportaudio.la
PAINC = include/portaudio.h

PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \
-export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio|PaOSS|PaWasapi|PaWasapiWinrt|PaWinMME)_.*" \
-export-symbols-regex "(Pa|PaMacCore|PaPulseAudio|PaJack|PaAlsa|PaAsio|PaOSS|PaWasapi|PaWasapiWinrt|PaWinMME)_.*" \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)

COMMON_OBJS = \
Expand All @@ -66,7 +66,7 @@ LOOPBACK_OBJS = \
qa/loopback/src/test_audio_analyzer.o \
qa/loopback/src/write_wav.o \
qa/loopback/src/paqa.o

EXAMPLES = \
bin/pa_devs \
bin/pa_fuzz \
Expand All @@ -82,7 +82,7 @@ SELFTESTS = \
bin/paqa_devs \
bin/paqa_errs \
bin/paqa_latency

TESTS = \
bin/patest1 \
bin/patest_buffer \
Expand Down Expand Up @@ -146,6 +146,7 @@ SRC_DIRS = \
src/hostapi/coreaudio \
src/hostapi/dsound \
src/hostapi/jack \
src/hostapi/pulseaudio \
src/hostapi/oss \
src/hostapi/skeleton \
src/hostapi/wasapi \
Expand Down
1 change: 1 addition & 0 deletions 3rdparty/portaudio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Please feel free to join. See http://www.portaudio.com for details.
src/hostapi/dsound = Windows Direct Sound
src/hostapi/jack = JACK Audio Connection Kit
src/hostapi/oss = Unix Open Sound System (OSS)
src/hostapi/pulseaudio = Sound system for POSIX OSes
src/hostapi/wasapi = Windows Vista WASAPI
src/hostapi/wdmks = Windows WDM Kernel Streaming
src/hostapi/wmme = Windows MultiMedia Extensions (MME)
Expand Down
122 changes: 122 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
cmake_minimum_required(VERSION 3.13)
cmake_policy(VERSION 3.13)

project(PortAudioCpp VERSION 19.8 LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

# Todo (multi-generator): Add support for multiple generators like: - {Debug,
# Release} x {Static, Dynamic} x {MT, MD (Windows only)}

# ##############################################################################
# sources and headers
# ##############################################################################

set(portaudiocpp-sources
source/portaudiocpp/BlockingStream.cxx
source/portaudiocpp/CFunCallbackStream.cxx
source/portaudiocpp/CallbackInterface.cxx
source/portaudiocpp/CallbackStream.cxx
source/portaudiocpp/CppFunCallbackStream.cxx
source/portaudiocpp/Device.cxx
source/portaudiocpp/DirectionSpecificStreamParameters.cxx
source/portaudiocpp/Exception.cxx
source/portaudiocpp/HostApi.cxx
source/portaudiocpp/InterfaceCallbackStream.cxx
source/portaudiocpp/MemFunCallbackStream.cxx
source/portaudiocpp/Stream.cxx
source/portaudiocpp/StreamParameters.cxx
source/portaudiocpp/System.cxx
source/portaudiocpp/SystemDeviceIterator.cxx
source/portaudiocpp/SystemHostApiIterator.cxx)

# since we don't GLOBing this variable must be kept up to date otherwise user
# installations are broken.
set(portaudiocpp-header-files
include/portaudiocpp/AutoSystem.hxx
include/portaudiocpp/BlockingStream.hxx
include/portaudiocpp/CFunCallbackStream.hxx
include/portaudiocpp/CallbackInterface.hxx
include/portaudiocpp/CallbackStream.hxx
include/portaudiocpp/CppFunCallbackStream.hxx
include/portaudiocpp/Device.hxx
include/portaudiocpp/DirectionSpecificStreamParameters.hxx
include/portaudiocpp/Exception.hxx
include/portaudiocpp/HostApi.hxx
include/portaudiocpp/InterfaceCallbackStream.hxx
include/portaudiocpp/MemFunCallbackStream.hxx
include/portaudiocpp/PortAudioCpp.hxx
include/portaudiocpp/SampleDataFormat.hxx
include/portaudiocpp/Stream.hxx
include/portaudiocpp/StreamParameters.hxx
include/portaudiocpp/System.hxx
include/portaudiocpp/SystemDeviceIterator.hxx
include/portaudiocpp/SystemHostApiIterator.hxx)

if(WIN32)
find_package(ASIO MODULE)
if(ASIO_FOUND)
list(APPEND portaudiocpp-sources source/portaudiocpp/AsioDeviceAdapter.cxx)
list(APPEND portaudiocpp-header-files
include/portaudiocpp/AsioDeviceAdapter.hxx)
endif()
endif()

# ##############################################################################
# portaudiocpp-targets
# ##############################################################################

add_library(portaudiocpp ${portaudiocpp-sources})
add_library(PortAudio::portaudiocpp ALIAS portaudiocpp) # For subdirectory build

find_package(PortAudio MODULE REQUIRED)

target_link_libraries(portaudiocpp PUBLIC PortAudio::portaudio)
target_include_directories(
portaudiocpp PUBLIC $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
set_target_properties(portaudiocpp PROPERTIES SOVERSION 2)
# Todo (modernize): update the code at least to c++14
# target_compile_features(portaudiocpp PUBLIC cxx_std_14)

# ## Export ###
include(GNUInstallDirs)

install(
TARGETS portaudiocpp
EXPORT PortAudioCppTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/portaudiocpp)

install(FILES ${portaudiocpp-header-files}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/portaudiocpp)

install(
EXPORT PortAudioCppTargets
FILE PortAudioCppTargets.cmake
NAMESPACE PortAudio::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/PortAudioCppConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

#use relative path, since CMAKE can't reconfigure on install with different prefix path
set(PC_PREFIX "\${pcfiledir}/../..")
configure_file(cmake/portaudiocpp.pc.in "${CMAKE_CURRENT_BINARY_DIR}/portaudiocpp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/portaudiocpp.pc"
CONFIGURATIONS Release RelWithDebInfo
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/PortAudioCppTargets.cmake")

check_required_components(PortAudioCpp)
81 changes: 81 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/modules/FindASIO.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#[=======================================================================[.rst:
FindASIO
--------

Finds the ASIO SDK by searching for the SDK ZIP in CMAKE_PREFIX_PATH and
CMAKE_CURRENT_BINARY_DIR. Alternatively, you may manually specify the path of
the SDK ZIP with the ASIO_SDK_ZIP_PATH variable, which can be used for caching
in CI scripts.

If the ZIP is found, this module extracts it.
The ZIP extraction is skipped if the unzipped SDK is found.

This module provides an `ASIO::host` IMPORT library target for building host
applications which use ASIO drivers. If you want to build an ASIO driver, this
module may serve as a useful start but you will need to modify it.

#]=======================================================================]

if(NOT WIN32)
message(WARNING "ASIO is only supported on Windows.")
set(ASIO_FOUND OFF)
return()
endif()

file(GLOB HEADER_FILE
"${CMAKE_CURRENT_BINARY_DIR}/asiosdk*/common/asio.h"
"${CMAKE_PREFIX_PATH}/asiosdk*/common/asio.h"
# The old build systems before PortAudio 19.8 used to look for the ASIO SDK
# in the same parent directory as the source code repository. This is no
# longer advised or documented but kept for backwards compatibility.
"${CMAKE_CURRENT_SOURCE_DIR}/../asiosdk*/common/asio.h"
)
if(NOT EXISTS "${HEADER_FILE}")
# The file(ARCHIVE_EXTRACT) command was added in CMake 3.18, so if using an
# older version of CMake, the user needs to extract it themselves.
if(CMAKE_VERSION VERSION_LESS 3.18)
message(STATUS "ASIO SDK NOT found. Download the ASIO SDK ZIP from "
"https://www.steinberg.net/asiosdk and extract it to "
"${CMAKE_PREFIX_PATH} or ${CMAKE_CURRENT_BINARY_DIR}"
)
return()
endif()
file(GLOB results
"${ASIO_SDK_ZIP_PATH}"
"${CMAKE_CURRENT_BINARY_DIR}/asiosdk*.zip"
"${CMAKE_PREFIX_PATH}/asiosdk*.zip"
"${CMAKE_CURRENT_SOURCE_DIR}/../asiosdk*.zip"
)
foreach(f ${results})
if(EXISTS "${f}")
message(STATUS "Extracting ASIO SDK ZIP archive: ${f}")
file(ARCHIVE_EXTRACT INPUT "${f}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
endforeach()
file(GLOB HEADER_FILE "${CMAKE_CURRENT_BINARY_DIR}/asiosdk*/common/asio.h")
endif()

get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY)
get_filename_component(ASIO_ROOT "${HEADER_DIR}" DIRECTORY)

if(ASIO_ROOT)
set(ASIO_FOUND TRUE)
message(STATUS "Found ASIO SDK: ${ASIO_ROOT}")

if(ASIO_FOUND AND NOT TARGET ASIO::host)
add_library(ASIO::host INTERFACE IMPORTED)
target_sources(ASIO::host INTERFACE
"${ASIO_ROOT}/common/asio.cpp"
"${ASIO_ROOT}/host/asiodrivers.cpp"
"${ASIO_ROOT}/host/pc/asiolist.cpp"
)
target_include_directories(ASIO::host INTERFACE
"${ASIO_ROOT}/common"
"${ASIO_ROOT}/host"
"${ASIO_ROOT}/host/pc"
)
target_link_libraries(ASIO::host INTERFACE ole32 uuid)
endif()
else()
message(STATUS "ASIO SDK NOT found")
endif()
39 changes: 39 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/modules/FindPortAudio.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

macro(handle_default)

endmacro()

if(TARGET PortAudio::portaudio)
# nothing to do
return()
endif()
# search for portaudio as cmake module
find_package(PortAudio CONFIG QUIET)
if(PortAudio_FOUND)
if(TARGET PortAudio::portaudio)
return()
elseif(TARGET portaudio)
# vcpkg and old portaudio installations do not provide the same targets
add_library(PortAudio::portaudio ALIAS portaudio)
return()
else()
message(FATAL_ERROR "PortAudio_FOUND but not target PortAudio::portaudio")
endif()
endif()

# search for portaudio via pkg-config

message(STATUS "portaudio could not be found via cmake, specify PortAudio_DIR.\n Searching for it via pkg-config")
find_package(PkgConfig REQUIRED)
pkg_check_modules(portaudio REQUIRED QUIET IMPORTED_TARGET GLOBAL portaudio-2.0)
add_library(PortAudio::portaudio ALIAS PkgConfig::portaudio)
return()

# include(FindPackageHandleStandardArgs)
# find_package_handle_standard_args(Foo
# FOUND_VAR Foo_FOUND
# REQUIRED_VARS
# Foo_LIBRARY
# Foo_INCLUDE_DIR
# VERSION_VAR Foo_VERSION
# )
12 changes: 12 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/portaudiocpp.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
prefix=@PC_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include

Name: PortAudioCpp
Description: Portable audio I/O C++ bindings
Version: 12
Requires: portaudio-2.0

Libs: -L${libdir} -lportaudiocpp
Cflags: -I${includedir}
Loading

0 comments on commit 963561c

Please sign in to comment.