From 1838041a379b6247a02a583137c79d5d076d9644 Mon Sep 17 00:00:00 2001 From: Andrei BENCSIK Date: Thu, 5 May 2022 21:56:27 +0300 Subject: [PATCH] Add FindSDL2 to simplify main CML * the FindSDL2 module forwards to CONFIG mode first * if that fails (eg. no -version.cmake or config not even present) it uses pkg-config * exports SDL2::SDL2 and SDL2::SDL2main as targets * fix missing IMPORTED_LOCATION for other build types in Vorbisfile --- CMakeLists.txt | 10 ++-- cmake/FindSDL2.cmake | 95 ++++++++++++++++++++++++++++++++++++++ cmake/FindVorbisFile.cmake | 4 +- src/CMakeLists.txt | 10 ++-- 4 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 cmake/FindSDL2.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7354e00d7ee..61affa5bac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -478,19 +478,15 @@ if(ENABLE_GAME OR ENABLE_TESTS) find_package(VorbisFile REQUIRED) find_package(PkgConfig REQUIRED) find_package(Fontconfig REQUIRED) + find_package(SDL2 2.0.8 REQUIRED) if(NOT MSVC) # for everything else, use pkgconfig - # find_package can't be used for SDL2 since at least as of Ubuntu 20.04 they forgot to include the sdl2-config-version.cmake, so cmake can't tell if it's >= 2.0.8 and thus rejects using it - # meanwhile SDL2_image and SDL2_mixer don't seem to have any cmake configuration available at all - # the best I could find is that the more modern cmake module support is only available if you build SDL2 yourself instead of using a distro-packaged version - # still wouldn't help for SDL2_image and SDL2_mixer though - pkg_check_modules(SDL2 REQUIRED sdl2>=2.0.8) + # SDL2_image and SDL2_mixer don't seem to have any cmake configuration available at all pkg_check_modules(SDL2IMAGE REQUIRED SDL2_image>=2.0.2) pkg_check_modules(SDL2MIXER REQUIRED SDL2_mixer>=2.0.0) else() - # for MSVC, vcpkg builds and provides SDL2-related modules for cmake to use, so use those + # for MSVC, vcpkg builds and provides custom SDL2-related modules for cmake to use, so use those # this also fixes the issue with our previous FindSDL2* scripts incorrectly using the Release version of these libs instead of the Debug version - find_package(SDL2 2.0.8 CONFIG REQUIRED) find_package(sdl2-image CONFIG REQUIRED) find_package(sdl2-mixer CONFIG REQUIRED) endif() diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake new file mode 100644 index 00000000000..05093da76be --- /dev/null +++ b/cmake/FindSDL2.cmake @@ -0,0 +1,95 @@ +#[=======================================================================[.rst: +FindSDL2 +-------- + +Find the SDL2 includes and libraries. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines the `IMPORTED` targets ``SDL2::SDL2`` and ``SDL2::SDL2main``, if +SDL2 has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + + SDL2_FOUND - True if SDL2 found. + SDL2_INCLUDE_DIRS - Where to find SDL2/SDL.h. + SDL2_LIBRARIES - Libraries when using SDL2. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +# first specifically look for the CMake config version of SDL2 (either system or package manager) +# provides two TARGETs SDL2::SDL2 and SDL2::SDL2Main +find_package(SDL2 QUIET NO_MODULE) + +# after the CONFIG type `find_package` we get, if available, a SDL2_VERSION var +# if we found the SDL2 cmake package then we are almost done +# we still need to check the version for some edge cases where the -version.cmake file +# is missing +if(SDL2_FOUND) + find_package_handle_standard_args(SDL2 HANDLE_COMPONENTS CONFIG_MODE) + + # in some cases the target is an ALIAS, we want the original + get_target_property(_SDL2_ORIGINAL_TARGET "SDL2::SDL2" ALIASED_TARGET) + + # if it's a regular target, just set it to SDL2::SDL2 + if(NOT _SDL2_ORIGINAL_TARGET) + set(_SDL2_ORIGINAL_TARGET "SDL2::SDL2") + endif() + + get_target_property(_SDL2_INCLUDE_DIRS_FROM_CONFIG "${_SDL2_ORIGINAL_TARGET}" INTERFACE_INCLUDE_DIRECTORIES) + + # in the original sdl2-config.cmake we get only /include/SDL2 and in vcpkg we that + /include/ + if(_SDL2_INCLUDE_DIRS_FROM_CONFIG MATCHES ".*/include/SDL2.*") + get_filename_component(_SDL2_INCLUDE_DIRS "${_SDL2_INCLUDE_DIRS_FROM_CONFIG}" DIRECTORY) + list(APPEND _SDL2_INCLUDE_DIRS_FROM_CONFIG "${_SDL2_INCLUDE_DIRS}") + # we can endup with a duplicate with vcpkg + list(REMOVE_DUPLICATES _SDL2_INCLUDE_DIRS_FROM_CONFIG) + + set_property(TARGET "${_SDL2_ORIGINAL_TARGET}" PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${_SDL2_INCLUDE_DIRS_FROM_CONFIG}") + endif() + + get_target_property(_SDL2_INCLUDE_DIRS_FROM_CONFIG "${_SDL2_ORIGINAL_TARGET}" INTERFACE_INCLUDE_DIRECTORIES) + + mark_as_advanced(SDL2_INCLUDE_DIRS SDL2_LIBRARIES) + + return() +endif() + +# let's try pkg-config +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_SDL2 REQUIRED sdl2>=${SDL2_FIND_VERSION}) +endif() + +find_package_handle_standard_args(SDL2 DEFAULT_MSG PC_SDL2_INCLUDE_DIRS PC_SDL2_LIBRARIES) + +if(SDL2_FOUND) + if(NOT TARGET SDL2::SDL2) + # the .pc file for SDL2 contains `/include/SDL2` which is different from the cmake version + # i.e. `/include` + get_filename_component(SDL2_INCLUDE_DIRS ${PC_SDL2_INCLUDE_DIRS} DIRECTORY) + + set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS} CACHE STRING "SDL2 include directories") + set(SDL2_LIBRARIES ${PC_SDL2_LIBRARIES} CACHE STRING "SDL2 libraries") + + mark_as_advanced(SDL2_INCLUDE_DIRS SDL2_LIBRARIES) + + add_library(SDL2::SDL2 INTERFACE IMPORTED) + set_target_properties(SDL2::SDL2 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}" + INTERFACE_LINK_DIRECTORIES "${PC_SDL2_LIBDIR}" + INTERFACE_LINK_LIBRARIES "${SDL2_LIBRARIES}") + endif() + + if(NOT TARGET SDL2::SDL2main) + # on *nix it seems that .pc files don't actually include libSDL2main, but for consistency's sake, + # let's add a phony library we can link with + add_library(SDL2::SDL2main INTERFACE IMPORTED) + endif() +endif() diff --git a/cmake/FindVorbisFile.cmake b/cmake/FindVorbisFile.cmake index 4b8e7cbcce2..94e8473cbdd 100644 --- a/cmake/FindVorbisFile.cmake +++ b/cmake/FindVorbisFile.cmake @@ -115,7 +115,7 @@ if(VORBISFILE_FOUND AND (NOT TARGET VorbisFile::VorbisFile)) if(VORBISFILE_LIBRARY_DEBUG) set_target_properties(VorbisFile::VorbisFile PROPERTIES IMPORTED_LOCATION_DEBUG "${VORBISFILE_LIBRARY_DEBUG}") set_target_properties(VorbisFile::VorbisFile PROPERTIES IMPORTED_LOCATION_RELEASE "${VORBISFILE_LIBRARY}") - else() - set_target_properties(VorbisFile::VorbisFile PROPERTIES IMPORTED_LOCATION "${VORBISFILE_LIBRARY}") endif() + # for the rest of build types + set_target_properties(VorbisFile::VorbisFile PROPERTIES IMPORTED_LOCATION "${VORBISFILE_LIBRARY}") endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5145f1f02e..0f3ab348b6a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,6 @@ include_directories(SYSTEM ${PANGOCAIRO_INCLUDE_DIRS}) include_directories(SYSTEM ${GETTEXT_INCLUDE_DIR}) include_directories(SYSTEM ${LIBDBUS_INCLUDE_DIRS}) if(NOT MSVC) - include_directories(SYSTEM ${SDL2_INCLUDE_DIRS}) include_directories(SYSTEM ${SDL2IMAGE_INCLUDE_DIRS}) include_directories(SYSTEM ${SDL2MIXER_INCLUDE_DIRS}) endif() @@ -59,7 +58,6 @@ set(game-external-libs if(NOT MSVC) set(game-external-libs ${game-external-libs} - ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES} ${SDL2MIXER_LIBRARIES} ) @@ -248,10 +246,10 @@ if(ENABLE_GAME) Boost::locale Boost::filesystem Fontconfig::Fontconfig + SDL2::SDL2 + SDL2::SDL2main ) if(MSVC) - target_link_libraries(wesnoth SDL2::SDL2) - target_link_libraries(wesnoth SDL2::SDL2main) target_link_libraries(wesnoth SDL2::SDL2_image) target_link_libraries(wesnoth SDL2::SDL2_mixer) endif() @@ -295,10 +293,10 @@ if(ENABLE_TESTS) Boost::filesystem Boost::unit_test_framework Fontconfig::Fontconfig + SDL2::SDL2 + SDL2::SDL2main ) if(MSVC) - target_link_libraries(boost_unit_tests SDL2::SDL2) - target_link_libraries(boost_unit_tests SDL2::SDL2main) target_link_libraries(boost_unit_tests SDL2::SDL2_image) target_link_libraries(boost_unit_tests SDL2::SDL2_mixer) endif()