From 95e6bfcd8cd219eee85588cf1e24781f5fd45e38 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 28 Mar 2021 22:06:02 -0400 Subject: [PATCH] Better support for vendoring - Allow ZLIB::ZLIB target to be provided by a unified build - Added ZMUSIC_INSTALL variable to allow disabling of install rules (mostly due to how install(EXPORT) works) - Static libraries don't need dllimport/dllexport on Windows - Fixed: INTERFACE include directory was missing from zmusic/zmusiclite targets when using with add_subdirectory - use_fast_math CMake function updated to allow source files to be passed (for GZDoom/Raze) --- CMakeLists.txt | 34 +++++++++++++---- cmake/ZUtility.cmake | 20 +++++++--- include/zmusic.h | 8 ++-- source/CMakeLists.txt | 65 +++++++++++++++++---------------- source/zmusic/zmusic_internal.h | 6 +-- thirdparty/CMakeLists.txt | 30 ++++++++------- 6 files changed, 97 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fbd9be..757491f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,12 +12,28 @@ include(ZUtility) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -# If building standalone give the user the option to build shared or static. -# Otherwise the vendoring project should set the variable. if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + # This project is being built standalone + + # Give user option to build shared or static option(BUILD_SHARED_LIBS "Build shared libraries" ON) -elseif(NOT DEFINED BUILD_SHARED_LIBS) - set(BUILD_SHARED_LIBS ON) + + # Enable install rules + set(ZMUSIC_INSTALL ON) +else() + # This project is being vendored by another project, set option default if + # the parent project doesn't provide them. + + if(NOT DEFINED BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ON) + endif() + + # Although install rules can be avoided with EXCLUDE_FROM_ALL on + # add_subdirectory, the EXPORT rules may place certain usage requirements on + # targets shared between the two projects. + if(NOT DEFINED ZMUSIC_INSTALL) + set(ZMUSIC_INSTALL OFF) + endif() endif() if(NOT CMAKE_BUILD_TYPE) @@ -110,10 +126,12 @@ configure_package_config_file( ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake ) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic - COMPONENT devel -) +if(ZMUSIC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic + COMPONENT devel + ) +endif() if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(CPACK_PACKAGE_CONTACT "First Last " CACHE STRING "Contact info for archive maintainer.") diff --git a/cmake/ZUtility.cmake b/cmake/ZUtility.cmake index 65cb320..9076017 100644 --- a/cmake/ZUtility.cmake +++ b/cmake/ZUtility.cmake @@ -120,10 +120,18 @@ function(require_strnicmp Tgt Visibility) endif() endfunction() -function(use_fast_math Tgt) - if(MSVC) - set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "/fp:fast" ) - elseif(ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE) - set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "-ffast-math" "-ffp-contract=fast" ) - endif() +function(use_fast_math) + foreach(Tgt IN LISTS ARGN) + if(TARGET Tgt) + set(TgtType TARGET) + else() + set(TgtType SOURCE) + endif() + + if(MSVC) + set_property("${TgtType}" "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "/fp:fast") + elseif(COMPILER_IS_GNUCXX_COMPATIBLE) + set_property("${TgtType}" "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "-ffast-math" "-ffp-contract=fast") + endif() + endforeach() endfunction() diff --git a/include/zmusic.h b/include/zmusic.h index 7de05c5..9b0937a 100644 --- a/include/zmusic.h +++ b/include/zmusic.h @@ -264,11 +264,11 @@ typedef struct ZMusicConfigurationSetting_ #ifndef ZMUSIC_INTERNAL -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC) #define DLL_IMPORT _declspec(dllimport) -#else // !_MSC_VER +#else #define DLL_IMPORT -#endif // _MSC_VER +#endif // Note that the internal 'class' definitions are not C compatible! typedef struct { int zm1; } *ZMusic_MidiSource; typedef struct { int zm2; } *ZMusic_MusicStream; @@ -419,4 +419,4 @@ typedef const ZMusicMidiOutDevice *(*pfn_ZMusic_GetMidiDevices)(int *pAmount); -#endif \ No newline at end of file +#endif diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 059451a..60b048e 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -152,13 +152,14 @@ use_fast_math(zmusiclite) # Although zmusic-obj puts the public include directory in our private include # list, we need to add it to the interface include directories for consumers. -target_include_directories(zmusic INTERFACE $) -target_include_directories(zmusiclite INTERFACE $) +target_include_directories(zmusic INTERFACE $ $) +target_include_directories(zmusiclite INTERFACE $ $) target_link_libraries_hidden(zmusic zmusic-obj adl oplsynth opn timidity timidityplus wildmidi) target_link_libraries_hidden(zmusiclite zmusic-obj) -target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1) +target_compile_definitions(zmusic PUBLIC $<$,STATIC_LIBRARY>:ZMUSIC_STATIC>) +target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1 PUBLIC $<$,STATIC_LIBRARY>:ZMUSIC_STATIC>) set_target_properties(zmusic zmusiclite PROPERTIES @@ -168,37 +169,39 @@ PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} ) -install(TARGETS zmusic EXPORT ZMusicFullTargets -PUBLIC_HEADER - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT devel -LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT full - NAMELINK_COMPONENT devel -) +if(ZMUSIC_INSTALL) + install(TARGETS zmusic EXPORT ZMusicFullTargets + PUBLIC_HEADER + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT devel + LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT full + NAMELINK_COMPONENT devel + ) -install(TARGETS zmusiclite EXPORT ZMusicLiteTargets -PUBLIC_HEADER - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT devel -LIBRARY - DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT lite - NAMELINK_COMPONENT devel -) + install(TARGETS zmusiclite EXPORT ZMusicLiteTargets + PUBLIC_HEADER + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT devel + LIBRARY + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT lite + NAMELINK_COMPONENT devel + ) -install(EXPORT ZMusicFullTargets - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic" - NAMESPACE ZMusic:: - COMPONENT devel -) + install(EXPORT ZMusicFullTargets + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic" + NAMESPACE ZMusic:: + COMPONENT devel + ) -install(EXPORT ZMusicLiteTargets - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic" - NAMESPACE ZMusic:: - COMPONENT devel -) + install(EXPORT ZMusicLiteTargets + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic" + NAMESPACE ZMusic:: + COMPONENT devel + ) +endif() if( MSVC ) option( ZMUSIC_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) diff --git a/source/zmusic/zmusic_internal.h b/source/zmusic/zmusic_internal.h index 629b49f..8f78e7f 100644 --- a/source/zmusic/zmusic_internal.h +++ b/source/zmusic/zmusic_internal.h @@ -1,13 +1,13 @@ #pragma once #define ZMUSIC_INTERNAL -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC) #define DLL_EXPORT __declspec(dllexport) #define DLL_IMPORT __declspec(dllexport) // without this the compiler complains. -#else // !_MSC_VER +#else #define DLL_EXPORT #define DLL_IMPORT -#endif // _MSC_VER +#endif typedef class MIDISource *ZMusic_MidiSource; typedef class MusInfo *ZMusic_MusicStream; diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 4f53410..161eb46 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -1,18 +1,20 @@ -option(FORCE_INTERNAL_ZLIB "Use internal zlib" OFF) -find_package(ZLIB QUIET) -if(ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB) - message(STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIRS}") - set_property(TARGET ZLIB::ZLIB PROPERTY IMPORTED_GLOBAL TRUE) - determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET ZLIB::ZLIB MODULE ZLIB) -else() - message(STATUS "Using internal zlib") - set(SKIP_INSTALL_ALL TRUE) # Avoid installing zlib alongside ZMusic - add_subdirectory(zlib) - add_library(ZLIB::ZLIB ALIAS z) +if(NOT TARGET ZLIB::ZLIB) + option(FORCE_INTERNAL_ZLIB "Use internal zlib" OFF) + find_package(ZLIB QUIET) + if(ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB) + message(STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIRS}") + set_property(TARGET ZLIB::ZLIB PROPERTY IMPORTED_GLOBAL TRUE) + determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET ZLIB::ZLIB MODULE ZLIB) + else() + message(STATUS "Using internal zlib") + set(SKIP_INSTALL_ALL TRUE) # Avoid installing zlib alongside ZMusic + add_subdirectory(zlib) + add_library(ZLIB::ZLIB ALIAS z) - # Setup variables for GME's CMakeLists - set(ZLIB_LIBRARY ZLIB::ZLIB) - get_property(ZLIB_INCLUDE_DIR TARGET ZLIB::ZLIB PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + # Setup variables for GME's CMakeLists + set(ZLIB_LIBRARY ZLIB::ZLIB) + get_property(ZLIB_INCLUDE_DIR TARGET ZLIB::ZLIB PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + endif() endif() # GME is not currently released in a way that's conducive to using as a system