From 7b99c589269436c33d50db9769d35ecfe94d65de Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Wed, 1 Nov 2023 19:34:32 +0000 Subject: [PATCH] Expose targets and versions for more dependencies (#6842) --- CMakeLists.txt | 2 - cmake/modules/BuildPlugin.cmake | 9 +- cmake/modules/FindFluidSynth.cmake | 2 +- cmake/modules/FindLame.cmake | 50 +++--- cmake/modules/FindOggVorbis.cmake | 132 +++++++--------- cmake/modules/FindPortaudio.cmake | 56 +++---- cmake/modules/FindSTK.cmake | 50 +++--- cmake/modules/FindSamplerate.cmake | 53 +++---- cmake/modules/FindSndFile.cmake | 63 ++++---- cmake/modules/ImportedTargetHelpers.cmake | 177 +++++++++++++++++++++- plugins/CMakeLists.txt | 5 +- plugins/GigPlayer/CMakeLists.txt | 13 +- plugins/Sf2Player/CMakeLists.txt | 5 +- plugins/Watsyn/CMakeLists.txt | 11 +- src/CMakeLists.txt | 28 ++-- 15 files changed, 382 insertions(+), 274 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ef6aaba3..5f388bf30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,8 +439,6 @@ IF(WANT_MP3LAME) SET(STATUS_MP3LAME "OK") ELSE(LAME_FOUND) SET(STATUS_MP3LAME "not found, please install libmp3lame-dev (or similar)") - SET(LAME_LIBRARIES "") - SET(LAME_INCLUDE_DIRS "") ENDIF(LAME_FOUND) ELSE(WANT_MP3LAME) SET(STATUS_MP3LAME "Disabled for build") diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index f8b3d3153..70e518c93 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -56,11 +56,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT}) - TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Xml) - - IF(LMMS_BUILD_WIN32) - TARGET_LINK_LIBRARIES(${PLUGIN_NAME} lmms) - ENDIF(LMMS_BUILD_WIN32) + target_link_libraries("${PLUGIN_NAME}" lmms Qt5::Widgets Qt5::Xml) INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}" @@ -70,10 +66,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) IF(LMMS_BUILD_APPLE) IF ("${PLUGIN_LINK}" STREQUAL "SHARED") SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") - ELSE() - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") ENDIF() - ADD_DEPENDENCIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) add_custom_command( diff --git a/cmake/modules/FindFluidSynth.cmake b/cmake/modules/FindFluidSynth.cmake index fcc00cd7d..70c40b8d8 100644 --- a/cmake/modules/FindFluidSynth.cmake +++ b/cmake/modules/FindFluidSynth.cmake @@ -34,7 +34,7 @@ if(FluidSynth_INCLUDE_DIR AND FluidSynth_LIBRARY) if(VCPKG_INSTALLED_DIR) include(ImportedTargetHelpers) - _get_vcpkg_library_configs(FluidSynth_IMPLIB_RELEASE FluidSynth_IMPLIB_DEBUG "${FluidSynth_LIBRARY}") + get_vcpkg_library_configs(FluidSynth_IMPLIB_RELEASE FluidSynth_IMPLIB_DEBUG "${FluidSynth_LIBRARY}") else() set(FluidSynth_IMPLIB_RELEASE "${FluidSynth_LIBRARY}") endif() diff --git a/cmake/modules/FindLame.cmake b/cmake/modules/FindLame.cmake index c3fb09c5b..3017dc5aa 100644 --- a/cmake/modules/FindLame.cmake +++ b/cmake/modules/FindLame.cmake @@ -1,37 +1,31 @@ -# - Try to find LAME -# Once done this will define +# Copyright (c) 2023 Dominic Clark # -# Lame_FOUND - system has liblame -# Lame_INCLUDE_DIRS - the liblame include directory -# Lame_LIBRARIES - The liblame libraries -# mp3lame::mp3lame - an imported target providing lame +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -find_package(mp3lame CONFIG QUIET) +include(ImportedTargetHelpers) -if(TARGET mp3lame::mp3lame) - # Extract details for find_package_handle_standard_args - get_target_property(Lame_LIBRARIES mp3lame::mp3lame LOCATION) - get_target_property(Lame_INCLUDE_DIRS mp3lame::mp3lame INTERFACE_INCLUDE_DIRECTORIES) -else() - find_path(Lame_INCLUDE_DIRS lame/lame.h) - find_library(Lame_LIBRARIES mp3lame) +find_package_config_mode_with_fallback(mp3lame mp3lame::mp3lame + LIBRARY_NAMES "mp3lame" + INCLUDE_NAMES "lame/lame.h" + PREFIX Lame +) - list(APPEND Lame_DEFINITIONS HAVE_LIBMP3LAME=1) +determine_version_from_source(Lame_VERSION mp3lame::mp3lame [[ + #include + #include - mark_as_advanced(Lame_INCLUDE_DIRS Lame_LIBRARIES Lame_DEFINITIONS) - - if(Lame_LIBRARIES AND Lame_INCLUDE_DIRS) - add_library(mp3lame::mp3lame UNKNOWN IMPORTED) - - set_target_properties(mp3lame::mp3lame PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Lame_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${Lame_DEFINITIONS}" - IMPORTED_LOCATION "${Lame_LIBRARIES}" - ) - endif() -endif() + auto main() -> int + { + auto version = lame_version_t{}; + get_lame_version_numerical(&version); + std::cout << version.major << "." << version.minor; + } +]]) include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Lame - REQUIRED_VARS Lame_LIBRARIES Lame_INCLUDE_DIRS + REQUIRED_VARS Lame_LIBRARY Lame_INCLUDE_DIRS + VERSION_VAR Lame_VERSION ) diff --git a/cmake/modules/FindOggVorbis.cmake b/cmake/modules/FindOggVorbis.cmake index 79a9ab406..cfbd73256 100644 --- a/cmake/modules/FindOggVorbis.cmake +++ b/cmake/modules/FindOggVorbis.cmake @@ -1,86 +1,68 @@ -# - Try to find the OggVorbis libraries -# Once done this will define +# Copyright (c) 2023 Dominic Clark # -# OGGVORBIS_FOUND - system has OggVorbis -# OGGVORBIS_VERSION - set either to 1 or 2 -# OGGVORBIS_INCLUDE_DIR - the OggVorbis include directory -# OGGVORBIS_LIBRARIES - The libraries needed to use OggVorbis -# OGG_LIBRARY - The Ogg library -# VORBIS_LIBRARY - The Vorbis library -# VORBISFILE_LIBRARY - The VorbisFile library -# VORBISENC_LIBRARY - The VorbisEnc library - -# Copyright (c) 2006, Richard Laerkaeng, -# -# Redistribution and use is allowed according to the terms of the BSD license. +# Redistribution and use is allowed according to the terms of the New BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. +include(ImportedTargetHelpers) -include (CheckLibraryExists) +find_package_config_mode_with_fallback(Ogg Ogg::ogg + LIBRARY_NAMES "ogg" + INCLUDE_NAMES "ogg/ogg.h" + PKG_CONFIG ogg +) -find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h) -find_path(OGG_INCLUDE_DIR ogg/ogg.h) +find_package_config_mode_with_fallback(Vorbis Vorbis::vorbis + LIBRARY_NAMES "vorbis" + INCLUDE_NAMES "vorbis/codec.h" + PKG_CONFIG vorbis + DEPENDS Ogg::ogg +) -find_library(OGG_LIBRARY NAMES ogg) -find_library(VORBIS_LIBRARY NAMES vorbis) -find_library(VORBISFILE_LIBRARY NAMES vorbisfile) -find_library(VORBISENC_LIBRARY NAMES vorbisenc) +find_package_config_mode_with_fallback(Vorbis Vorbis::vorbisfile + LIBRARY_NAMES "vorbisfile" + INCLUDE_NAMES "vorbis/vorbisfile.h" + PKG_CONFIG vorbisfile + DEPENDS Vorbis::vorbis + PREFIX VorbisFile +) +find_package_config_mode_with_fallback(Vorbis Vorbis::vorbisenc + LIBRARY_NAMES "vorbisenc" + INCLUDE_NAMES "vorbis/vorbisenc.h" + PKG_CONFIG vorbisenc + DEPENDS Vorbis::vorbis + PREFIX VorbisEnc +) -if (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) - set(OGGVORBIS_FOUND TRUE) +determine_version_from_source(Vorbis_VERSION Vorbis::vorbis [[ + #include + #include + #include - set(OGGVORBIS_LIBRARIES ${OGG_LIBRARY} ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBISENC_LIBRARY}) + auto main() -> int + { + // Version string has the format "org name version" + const auto version = std::string_view{vorbis_version_string()}; + const auto nameBegin = version.find(' ') + 1; + const auto versionBegin = version.find(' ', nameBegin) + 1; + std::cout << version.substr(versionBegin); + } +]]) - set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES}) - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OGGVORBIS_LIBRARIES}) - check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2) - set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP}) - - if (HAVE_LIBVORBISENC2) - set (OGGVORBIS_VERSION 2) - else (HAVE_LIBVORBISENC2) - set (OGGVORBIS_VERSION 1) - endif (HAVE_LIBVORBISENC2) - -else (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) - set (OGGVORBIS_VERSION) - set(OGGVORBIS_FOUND FALSE) -endif (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) - - -if (OGGVORBIS_FOUND) - if (NOT OggVorbis_FIND_QUIETLY) - message(STATUS "Found OggVorbis: ${OGGVORBIS_LIBRARIES}") - endif (NOT OggVorbis_FIND_QUIETLY) -else (OGGVORBIS_FOUND) - if (OggVorbis_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find OggVorbis libraries") - endif (OggVorbis_FIND_REQUIRED) - if (NOT OggVorbis_FIND_QUITELY) - message(STATUS "Could NOT find OggVorbis libraries") - endif (NOT OggVorbis_FIND_QUITELY) -endif (OGGVORBIS_FOUND) - -#check_include_files(vorbis/vorbisfile.h HAVE_VORBISFILE_H) -#check_library_exists(ogg ogg_page_version "" HAVE_LIBOGG) -#check_library_exists(vorbis vorbis_info_init "" HAVE_LIBVORBIS) -#check_library_exists(vorbisfile ov_open "" HAVE_LIBVORBISFILE) -#check_library_exists(vorbisenc vorbis_info_clear "" HAVE_LIBVORBISENC) -#check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2) - -#if (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) -# message(STATUS "Ogg/Vorbis found") -# set (VORBIS_LIBS "-lvorbis -logg") -# set (VORBISFILE_LIBS "-lvorbisfile") -# set (VORBISENC_LIBS "-lvorbisenc") -# set (OGGVORBIS_FOUND TRUE) -# if (HAVE_LIBVORBISENC2) -# set (HAVE_VORBIS 2) -# else (HAVE_LIBVORBISENC2) -# set (HAVE_VORBIS 1) -# endif (HAVE_LIBVORBISENC2) -#else (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) -# message(STATUS "Ogg/Vorbis not found") -#endif (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OggVorbis + REQUIRED_VARS + Ogg_LIBRARY + Ogg_INCLUDE_DIRS + Vorbis_LIBRARY + Vorbis_INCLUDE_DIRS + VorbisFile_LIBRARY + VorbisFile_INCLUDE_DIRS + VorbisEnc_LIBRARY + VorbisEnc_INCLUDE_DIRS + # This only reports the Vorbis version - Ogg can have a different version, + # so if we ever care about that, it should be split off into a different + # find module. + VERSION_VAR Vorbis_VERSION +) diff --git a/cmake/modules/FindPortaudio.cmake b/cmake/modules/FindPortaudio.cmake index f9c7699f4..e7cfa1383 100644 --- a/cmake/modules/FindPortaudio.cmake +++ b/cmake/modules/FindPortaudio.cmake @@ -1,44 +1,34 @@ -# Copyright (c) 2022 Dominic Clark +# Copyright (c) 2023 Dominic Clark # # Redistribution and use is allowed according to the terms of the New BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# Try config mode if possible -find_package(portaudio CONFIG QUIET) +include(ImportedTargetHelpers) -if(TARGET portaudio) - # Extract details for find_package_handle_standard_args - get_target_property(Portaudio_LIBRARY portaudio LOCATION) - get_target_property(Portaudio_INCLUDE_DIR portaudio INTERFACE_INCLUDE_DIRECTORIES) -else() - # Attempt to find PortAudio using PkgConfig, if we have it - find_package(PkgConfig QUIET) - if(PKG_CONFIG_FOUND) - pkg_check_modules(PORTAUDIO_PKG portaudio-2.0) - endif() +find_package_config_mode_with_fallback(portaudio portaudio + LIBRARY_NAMES "portaudio" + INCLUDE_NAMES "portaudio.h" + PKG_CONFIG portaudio-2.0 + PREFIX Portaudio +) - # Find the library and headers using the results from PkgConfig as a guide - find_library(Portaudio_LIBRARY - NAMES "portaudio" - HINTS ${PORTAUDIO_PKG_LIBRARY_DIRS} - ) +determine_version_from_source(Portaudio_VERSION portaudio [[ + #include + #include "portaudio.h" - find_path(Portaudio_INCLUDE_DIR - NAMES "portaudio.h" - HINTS ${PORTAUDIO_PKG_INCLUDE_DIRS} - ) - - # Create an imported target for PortAudio if we succeeded in finding it. - if(Portaudio_LIBRARY AND Portaudio_INCLUDE_DIR) - add_library(portaudio UNKNOWN IMPORTED) - set_target_properties(portaudio PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Portaudio_INCLUDE_DIR}" - IMPORTED_LOCATION "${Portaudio_LIBRARY}" - ) - endif() -endif() + auto main() -> int + { + // Version number has the format 0xMMmmpp + const auto version = Pa_GetVersion(); + std::cout << ((version >> 16) & 0xff) + << "." << ((version >> 8) & 0xff) + << "." << ((version >> 0) & 0xff); + } +]]) include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Portaudio - REQUIRED_VARS Portaudio_LIBRARY Portaudio_INCLUDE_DIR + REQUIRED_VARS Portaudio_LIBRARY Portaudio_INCLUDE_DIRS + VERSION_VAR Portaudio_VERSION ) diff --git a/cmake/modules/FindSTK.cmake b/cmake/modules/FindSTK.cmake index 0718f5039..5564d24f8 100644 --- a/cmake/modules/FindSTK.cmake +++ b/cmake/modules/FindSTK.cmake @@ -1,39 +1,27 @@ -# Try config mode first -find_package(unofficial-libstk CONFIG QUIET) +include(ImportedTargetHelpers) -if(TARGET unofficial::libstk::libstk) - # Extract details for find_package_handle_standard_args - get_target_property(STK_LIBRARY unofficial::libstk::libstk LOCATION) - get_target_property(STK_INCLUDE_DIR unofficial::libstk::libstk INTERFACE_INCLUDE_DIRECTORIES) -else() - find_path(STK_INCLUDE_DIR - NAMES stk/Stk.h - PATH /usr/include /usr/local/include "${CMAKE_INSTALL_PREFIX}/include" "${CMAKE_FIND_ROOT_PATH}/include" +# TODO CMake 3.18: Alias this target to something less hideous +find_package_config_mode_with_fallback(unofficial-libstk unofficial::libstk::libstk + LIBRARY_NAMES "stk" + INCLUDE_NAMES "stk/Stk.h" + LIBRARY_HINTS "/usr/lib" "/usr/local/lib" "${CMAKE_INSTALL_PREFIX}/lib" "${CMAKE_FIND_ROOT_PATH}/lib" + INCLUDE_HINTS "/usr/include" "/usr/local/include" "${CMAKE_INSTALL_PREFIX}/include" "${CMAKE_FIND_ROOT_PATH}/include" + PREFIX STK +) + +# Find STK rawwave path +if(STK_INCLUDE_DIRS) + list(GET STK_INCLUDE_DIRS 0 STK_INCLUDE_DIR) + find_path(STK_RAWWAVE_ROOT + NAMES silence.raw sinewave.raw + HINTS "${STK_INCLUDE_DIR}/.." + PATH_SUFFIXES share/stk/rawwaves share/libstk/rawwaves ) - - find_library(STK_LIBRARY - NAMES stk - PATH /usr/lib /usr/local/lib "${CMAKE_INSTALL_PREFIX}/lib" "${CMAKE_FIND_ROOT_PATH}/lib" - ) - - if(STK_INCLUDE_DIR AND STK_LIBRARY) - # Yes, this target name is hideous, but it matches that provided by vcpkg - add_library(unofficial::libstk::libstk UNKNOWN IMPORTED) - set_target_properties(unofficial::libstk::libstk PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${STK_INCLUDE_DIR}" - IMPORTED_LOCATION "${STK_LIBRARY}" - ) - endif() endif() -# find STK rawwave path -find_path(STK_RAWWAVE_ROOT - NAMES silence.raw sinewave.raw - HINTS "${STK_INCLUDE_DIR}/.." - PATH_SUFFIXES share/stk/rawwaves share/libstk/rawwaves -) - include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(STK REQUIRED_VARS STK_LIBRARY STK_INCLUDE_DIR + # STK doesn't appear to expose its version, so we can't pass it here ) diff --git a/cmake/modules/FindSamplerate.cmake b/cmake/modules/FindSamplerate.cmake index 53b69f6c7..683748c59 100644 --- a/cmake/modules/FindSamplerate.cmake +++ b/cmake/modules/FindSamplerate.cmake @@ -1,34 +1,35 @@ -# FindFFTW.cmake - Try to find FFTW3 -# Copyright (c) 2018 Lukas W -# This file is MIT licensed. -# See http://opensource.org/licenses/MIT +# Copyright (c) 2023 Dominic Clark +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -find_package(PkgConfig QUIET) -if(PKG_CONFIG_FOUND) - pkg_check_modules(SAMPLERATE_PKG samplerate) -endif() +include(ImportedTargetHelpers) -find_path(SAMPLERATE_INCLUDE_DIR - NAMES samplerate.h - PATHS ${SAMPLERATE_PKG_INCLUDE_DIRS} +find_package_config_mode_with_fallback(SampleRate SampleRate::samplerate + LIBRARY_NAMES "samplerate" "libsamplerate" "libsamplerate-0" + INCLUDE_NAMES "samplerate.h" + PKG_CONFIG samplerate + PREFIX Samplerate ) -set(SAMPLERATE_NAMES samplerate libsamplerate) -if(Samplerate_FIND_VERSION_MAJOR) - list(APPEND SAMPLERATE_NAMES libsamplerate-${Samplerate_FIND_VERSION_MAJOR}) -else() - list(APPEND SAMPLERATE_NAMES libsamplerate-0) -endif() +determine_version_from_source(Samplerate_VERSION SampleRate::samplerate [[ + #include + #include + #include -find_library(SAMPLERATE_LIBRARY - NAMES ${SAMPLERATE_NAMES} - PATHS ${SAMPLERATE_PKG_LIBRARY_DIRS} -) + auto main() -> int + { + // Version string has the format "name-version copyright" + const auto version = std::string_view{src_get_version()}; + const auto begin = version.find('-') + 1; + const auto end = version.find(' ', begin); + std::cout << version.substr(begin, end - begin); + } +]]) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(SAMPLERATE DEFAULT_MSG SAMPLERATE_LIBRARY SAMPLERATE_INCLUDE_DIR) -mark_as_advanced(SAMPLERATE_INCLUDE_DIR SAMPLERATE_LIBRARY ) - -set(SAMPLERATE_LIBRARIES ${SAMPLERATE_LIBRARY} ) -set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE_INCLUDE_DIR}) +find_package_handle_standard_args(Samplerate + REQUIRED_VARS Samplerate_LIBRARY Samplerate_INCLUDE_DIRS + VERSION_VAR Samplerate_VERSION +) diff --git a/cmake/modules/FindSndFile.cmake b/cmake/modules/FindSndFile.cmake index 28ebb7bb7..d69fa6331 100644 --- a/cmake/modules/FindSndFile.cmake +++ b/cmake/modules/FindSndFile.cmake @@ -1,39 +1,34 @@ -# FindSndFile.cmake - Try to find libsndfile -# Copyright (c) 2018 Lukas W -# This file is MIT licensed. -# See http://opensource.org/licenses/MIT +# Copyright (c) 2023 Dominic Clark +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# Try pkgconfig for hints -find_package(PkgConfig QUIET) -if(PKG_CONFIG_FOUND) - pkg_check_modules(SNDFILE_PKG sndfile) -endif(PKG_CONFIG_FOUND) -set(SndFile_DEFINITIONS ${SNDFILE_PKG_CFLAGS_OTHER}) +include(ImportedTargetHelpers) -if(WIN32) - # Try Vcpkg - find_package(LibSndFile ${SndFile_FIND_VERSION} CONFIG QUIET) - if(LibSndFile_FOUND) - get_target_property(LibSndFile_Location sndfile-shared LOCATION) - get_target_property(LibSndFile_Include_Path sndfile-shared INTERFACE_INCLUDE_DIRECTORIES) - get_filename_component(LibSndFile_Path LibSndFile_Location PATH) - endif() -endif() - -find_path(SNDFILE_INCLUDE_DIR - NAMES sndfile.h - PATHS ${SNDFILE_PKG_INCLUDE_DIRS} ${LibSndFile_Include_Path} +find_package_config_mode_with_fallback(SndFile SndFile::sndfile + LIBRARY_NAMES "sndfile" "libsndfile" "libsndfile-1" + INCLUDE_NAMES "sndfile.h" + PKG_CONFIG sndfile ) -find_library(SNDFILE_LIBRARY - NAMES sndfile libsndfile libsndfile-1 - PATHS ${SNDFILE_PKG_LIBRARY_DIRS} ${LibSndFile_Path} +determine_version_from_source(SndFile_VERSION SndFile::sndfile [[ + #include + #include + #include + + auto main() -> int + { + // Version string has the format "name-version", optionally followed by "-exp" + const auto version = std::string_view{sf_version_string()}; + const auto begin = version.find('-') + 1; + const auto end = version.find('-', begin); + std::cout << version.substr(begin, end - begin); + } +]]) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(SndFile + REQUIRED_VARS SndFile_LIBRARY SndFile_INCLUDE_DIRS + VERSION_VAR SndFile_VERSION ) - -find_package(PackageHandleStandardArgs) -find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR) - -set(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY}) -set(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR}) - -mark_as_advanced(SNDFILE_LIBRARY SNDFILE_LIBRARIES SNDFILE_INCLUDE_DIR SNDFILE_INCLUDE_DIRS) diff --git a/cmake/modules/ImportedTargetHelpers.cmake b/cmake/modules/ImportedTargetHelpers.cmake index 87b3aeedc..d3d979901 100644 --- a/cmake/modules/ImportedTargetHelpers.cmake +++ b/cmake/modules/ImportedTargetHelpers.cmake @@ -1,7 +1,178 @@ +# ImportedTargetHelpers.cmake - various helper functions for use in find modules. +# +# Copyright (c) 2022-2023 Dominic Clark +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# If the version variable is not yet set, build the source linked to the target, +# run it, and set the version variable to the output. Useful for libraries which +# do not expose the version information in a header where it can be extracted +# with regular expressions, but do provide a function to get the version. +# +# Usage: +# determine_version_from_source( +# # The cache variable in which to store the computed version +# # The target which the source will link to +# # The source code to determine the version +# ) +function(determine_version_from_source _version_out _target _source) + # Return if we already know the version, or the target was not found + if(NOT "${${_version_out}}" STREQUAL "" OR NOT TARGET "${_target}") + return() + endif() + + # Return with a notice if cross-compiling, since we are unlikely to be able + # to run the compiled source + if(CMAKE_CROSSCOMPILING) + message( + "${_target} was found but the version could not be determined automatically.\n" + "Set the cache variable `${_version_out}` to the version you have installed." + ) + return() + endif() + + # Write the source code to a temporary file + string(SHA1 _source_hash "${_source}") + set(_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_source_hash}.cpp") + file(WRITE "${_source_file}" "${_source}") + + # Build and run the temporary file to get the version + # TODO CMake 3.25: Use the new signature for try_run which has a NO_CACHE + # option and doesn't require separate file management. + try_run( + _dvfs_run_result _dvfs_compile_result "${CMAKE_CURRENT_BINARY_DIR}" + SOURCES "${_source_file}" + LINK_LIBRARIES "${_target}" + CXX_STANDARD 17 + RUN_OUTPUT_VARIABLE _run_output + COMPILE_OUTPUT_VARIABLE _compile_output + ) + + # Clean up the temporary file + file(REMOVE "${_source_file}") + + # Set the version if the run was successful, using a cache variable since + # this version check may be relatively expensive. Otherwise, log the error + # and inform the user. + if(_dvfs_run_result EQUAL "0") + set("${_version_out}" "${_run_output}" CACHE INTERNAL "Version of ${_target}") + else() + message(DEBUG "${_compile_output}") + message( + "${_target} was found but the version could not be determined automatically.\n" + "Set the cache variable `${_version_out}` to the version you have installed." + ) + endif() +endfunction() + +# Search for a package using config mode. If this fails to find the desired +# target, use the specified fallbacks and add the target if they succeed. Set +# the variables `prefix_LIBRARY`, `prefix_INCLUDE_DIRS`, and `prefix_VERSION` +# if found for the caller to pass to `find_package_handle_standard_args`. +# +# Usage: +# find_package_config_mode_with_fallback( +# # The package to search for with config mode +# # The target to expect from config mode, or define if not found +# LIBRARY_NAMES names... # Possible library names to search for as a fallback +# INCLUDE_NAMES names... # Possible header names to search for as a fallback +# [PKG_CONFIG ] # The pkg-config name to search for as a fallback +# [LIBRARY_HINTS hints...] # Locations to look for libraries +# [INCLUDE_HINTS hints...] # Locations to look for headers +# [DEPENDS dependencies...] # Dependencies of the target - added to INTERFACE_LINK_LIBRARIES, and will fail if not found +# [PREFIX ] # The prefix for result variables - defaults to the package name +# ) +function(find_package_config_mode_with_fallback _fpcmwf_PACKAGE_NAME _fpcmwf_TARGET_NAME) + # Parse remaining arguments + set(_options "") + set(_one_value_args "PKG_CONFIG" "PREFIX") + set(_multi_value_args "LIBRARY_NAMES" "LIBRARY_HINTS" "INCLUDE_NAMES" "INCLUDE_HINTS" "DEPENDS") + cmake_parse_arguments(PARSE_ARGV 2 _fpcmwf "${_options}" "${_one_value_args}" "${_multi_value_args}") + + # Compute result variable names + if(NOT DEFINED _fpcmwf_PREFIX) + set(_fpcmwf_PREFIX "${_fpcmwf_PACKAGE_NAME}") + endif() + set(_version_var "${_fpcmwf_PREFIX}_VERSION") + set(_library_var "${_fpcmwf_PREFIX}_LIBRARY") + set(_include_var "${_fpcmwf_PREFIX}_INCLUDE_DIRS") + + # Try config mode if possible + find_package("${_fpcmwf_PACKAGE_NAME}" CONFIG QUIET) + + if(TARGET "${_fpcmwf_TARGET_NAME}") + # Extract package details from existing target + get_target_property("${_library_var}" "${_fpcmwf_TARGET_NAME}" LOCATION) + get_target_property("${_include_var}" "${_fpcmwf_TARGET_NAME}" INTERFACE_INCLUDE_DIRECTORIES) + if(DEFINED "${_fpcmwf_PACKAGE_NAME}_VERSION") + set("${_version_var}" "${${_fpcmwf_PACKAGE_NAME}_VERSION}") + endif() + else() + # Check whether the dependencies exist + foreach(_dependency IN LISTS _fpcmwf_DEPENDS) + if(NOT TARGET "${_dependency}") + return() + endif() + endforeach() + + # Attempt to find the package using pkg-config, if we have it and it was requested + set(_pkg_config_prefix "${_fpcmwf_PKG_CONFIG}_PKG") + if(DEFINED _fpcmwf_PKG_CONFIG) + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_check_modules("${_pkg_config_prefix}" QUIET "${_fpcmwf_PKG_CONFIG}") + if("${${_pkg_config_prefix}_FOUND}") + set("${_version_var}" "${${_pkg_config_prefix}_VERSION}") + endif() + endif() + endif() + + # Find the library and headers using the results from pkg-config as a guide + find_library("${_library_var}" + NAMES ${_fpcmwf_LIBRARY_NAMES} + HINTS ${${_pkg_config_prefix}_LIBRARY_DIRS} ${_fpcmwf_LIBRARY_HINTS} + ) + + find_path("${_include_var}" + NAMES ${_fpcmwf_INCLUDE_NAMES} + HINTS ${${_pkg_config_prefix}_INCLUDE_DIRS} ${_fpcmwf_INCLUDE_HINTS} + ) + + # Create an imported target if we succeeded in finding the package + if(${_library_var} AND ${_include_var}) + add_library("${_fpcmwf_TARGET_NAME}" UNKNOWN IMPORTED) + set_target_properties("${_fpcmwf_TARGET_NAME}" PROPERTIES + IMPORTED_LOCATION "${${_library_var}}" + INTERFACE_INCLUDE_DIRECTORIES "${${_include_var}}" + INTERFACE_LINK_LIBRARIES "${_fpcmwf_DEPENDS}" + ) + endif() + + mark_as_advanced("${_library_var}" "${_include_var}") + endif() + + # Return results to caller + if(DEFINED "${_version_var}") + set("${_version_var}" "${${_version_var}}" PARENT_SCOPE) + else() + unset("${_version_var}" PARENT_SCOPE) + endif() + set("${_library_var}" "${${_library_var}}" PARENT_SCOPE) + set("${_include_var}" "${${_include_var}}" PARENT_SCOPE) +endfunction() + # Given a library in vcpkg, find appropriate debug and release versions. If only -# one version exists, it is used as the release version, and the debug version -# is not set. -function(_get_vcpkg_library_configs _release_out _debug_out _library) +# one version exists, use it as the release version, and do not set the debug +# version. +# +# Usage: +# get_vcpkg_library_configs( +# # Variable in which to store the path to the release version of the library +# # Variable in which to store the path to the debug version of the library +# # Known path to some version of the library +# ) +function(get_vcpkg_library_configs _release_out _debug_out _library) # We want to do all operations within the vcpkg directory file(RELATIVE_PATH _lib_relative "${VCPKG_INSTALLED_DIR}" "${_library}") diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9a71be4b8..04862cac1 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,10 +9,7 @@ IF(LMMS_BUILD_APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") ENDIF() -INCLUDE_DIRECTORIES( - ${SAMPLERATE_INCLUDE_DIRS} - "${CMAKE_BINARY_DIR}/src" -) +include_directories("${CMAKE_BINARY_DIR}/src") # See cmake/modules/PluginList.cmake FOREACH(PLUGIN ${PLUGIN_LIST}) diff --git a/plugins/GigPlayer/CMakeLists.txt b/plugins/GigPlayer/CMakeLists.txt index 24db813bd..7b634b605 100644 --- a/plugins/GigPlayer/CMakeLists.txt +++ b/plugins/GigPlayer/CMakeLists.txt @@ -12,8 +12,13 @@ if(LMMS_HAVE_GIG) add_definitions(${GCC_GIG_COMPILE_FLAGS}) endif(LMMS_BUILD_WIN32) - LINK_DIRECTORIES(${GIG_LIBRARY_DIRS} ${SAMPLERATE_LIBRARY_DIRS}) - LINK_LIBRARIES(${GIG_LIBRARIES} ${SAMPLERATE_LIBRARIES}) - BUILD_PLUGIN(gigplayer GigPlayer.cpp GigPlayer.h PatchesDialog.cpp PatchesDialog.h PatchesDialog.ui MOCFILES GigPlayer.h PatchesDialog.h UICFILES PatchesDialog.ui EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png") + link_directories(${GIG_LIBRARY_DIRS}) + link_libraries(${GIG_LIBRARIES}) + build_plugin(gigplayer + GigPlayer.cpp GigPlayer.h PatchesDialog.cpp PatchesDialog.h PatchesDialog.ui + MOCFILES GigPlayer.h PatchesDialog.h + UICFILES PatchesDialog.ui + EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png" + ) + target_link_libraries(gigplayer SampleRate::samplerate) endif(LMMS_HAVE_GIG) - diff --git a/plugins/Sf2Player/CMakeLists.txt b/plugins/Sf2Player/CMakeLists.txt index 4679a94bd..1d004a6c5 100644 --- a/plugins/Sf2Player/CMakeLists.txt +++ b/plugins/Sf2Player/CMakeLists.txt @@ -1,13 +1,10 @@ if(LMMS_HAVE_FLUIDSYNTH) include(BuildPlugin) - include_directories(${SAMPLERATE_INCLUDE_DIRS}) - link_directories(${SAMPLERATE_LIBRARY_DIRS}) - link_libraries(${SAMPLERATE_LIBRARIES}) build_plugin(sf2player Sf2Player.cpp Sf2Player.h PatchesDialog.cpp PatchesDialog.h PatchesDialog.ui MOCFILES Sf2Player.h PatchesDialog.h UICFILES PatchesDialog.ui EMBEDDED_RESOURCES *.png ) - target_link_libraries(sf2player fluidsynth) + target_link_libraries(sf2player fluidsynth SampleRate::samplerate) endif() diff --git a/plugins/Watsyn/CMakeLists.txt b/plugins/Watsyn/CMakeLists.txt index 5aec12a46..b43abbb07 100644 --- a/plugins/Watsyn/CMakeLists.txt +++ b/plugins/Watsyn/CMakeLists.txt @@ -1,5 +1,8 @@ -INCLUDE(BuildPlugin) +include(BuildPlugin) -LINK_DIRECTORIES(${SAMPLERATE_LIBRARY_DIRS}) -LINK_LIBRARIES(${SAMPLERATE_LIBRARIES}) -BUILD_PLUGIN(watsyn Watsyn.cpp Watsyn.h MOCFILES Watsyn.h EMBEDDED_RESOURCES *.png) +build_plugin(watsyn + Watsyn.cpp Watsyn.h + MOCFILES Watsyn.h + EMBEDDED_RESOURCES *.png +) +target_link_libraries(watsyn SampleRate::samplerate) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f483d8b41..c074ea2ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,8 +58,6 @@ FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}") ADD_DEFINITIONS(-DLIB_DIR="${LIB_DIR_RELATIVE}" -DPLUGIN_DIR="${PLUGIN_DIR_RELATIVE}" ${PULSEAUDIO_DEFINITIONS}) INCLUDE_DIRECTORIES( ${JACK_INCLUDE_DIRS} - ${SAMPLERATE_INCLUDE_DIRS} - ${SNDFILE_INCLUDE_DIRS} ${SNDIO_INCLUDE_DIRS} ${FFTW3F_INCLUDE_DIRS} ) @@ -79,10 +77,6 @@ IF(NOT ("${PULSEAUDIO_INCLUDE_DIR}" STREQUAL "")) INCLUDE_DIRECTORIES("${PULSEAUDIO_INCLUDE_DIR}") ENDIF() -IF(NOT ("${OGGVORBIS_INCLUDE_DIR}" STREQUAL "")) - INCLUDE_DIRECTORIES("${OGGVORBIS_INCLUDE_DIR}") -ENDIF() - IF(NOT ("${LV2_INCLUDE_DIRS}" STREQUAL "")) INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS}) ENDIF() @@ -170,6 +164,10 @@ if(LMMS_HAVE_MP3LAME) list(APPEND EXTRA_LIBRARIES mp3lame::mp3lame) endif() +if(LMMS_HAVE_OGGVORBIS) + list(APPEND EXTRA_LIBRARIES Vorbis::vorbisenc Vorbis::vorbisfile) +endif() + if(LMMS_USE_MINGW_STD_THREADS) list(APPEND EXTRA_LIBRARIES mingw_stdthreads) endif() @@ -184,15 +182,14 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} ${SNDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} - ${OGGVORBIS_LIBRARIES} ${LV2_LIBRARIES} ${SUIL_LIBRARIES} ${LILV_LIBRARIES} - ${SAMPLERATE_LIBRARIES} - ${SNDFILE_LIBRARIES} ${FFTW3F_LIBRARIES} - ${EXTRA_LIBRARIES} rpmalloc + SampleRate::samplerate + SndFile::sndfile + ${EXTRA_LIBRARIES} ) # Expose required libs for tests binary @@ -211,10 +208,11 @@ FOREACH(LIB ${LMMS_REQUIRED_LIBS}) ENDIF() ENDFOREACH() +set_target_properties(lmms PROPERTIES + ENABLE_EXPORTS ON +) + IF(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES(lmms PROPERTIES - ENABLE_EXPORTS ON - ) IF(NOT MSVC) SET_PROPERTY(TARGET lmms APPEND_STRING PROPERTY LINK_FLAGS " -mwindows" @@ -228,10 +226,6 @@ IF(LMMS_BUILD_WIN32) ) ENDIF() ELSE() - IF(NOT LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") - ENDIF(NOT LMMS_BUILD_APPLE) - if(CMAKE_INSTALL_MANDIR) SET(INSTALL_MANDIR ${CMAKE_INSTALL_MANDIR}) ELSE(CMAKE_INSTALL_MANDIR)