cmake: make SDL2Config.cmake compatible with autotools' sdl2-config.cmake

This commit is contained in:
Anonymous Maarten 2022-06-03 20:12:52 +02:00 committed by Sam Lantinga
parent 9ff8f29f43
commit 5ec2d46f47
3 changed files with 93 additions and 139 deletions

View file

@ -287,7 +287,7 @@ if(MSVC)
endif()
endif()
# Those are used for pkg-config and friends, so that the SDL2.pc, sdl2-config,
# Those are used for pkg-config and friends, so that the sdl2.pc, sdl2-config,
# etc. are created correctly.
set(SDL_LIBS "-lSDL2")
set(SDL_CFLAGS "")
@ -312,7 +312,7 @@ if(CYGWIN)
HAVE_GCC_NO_CYGWIN)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_GCC_NO_CYGWIN)
list(APPEND EXTRA_LDFLAGS "-mno-cygwin")
list(APPEND EXTRA_LDFLAGS_BUILD "-mno-cygwin")
list(APPEND SDL_LIBS "-mno-cygwin")
endif()
set(SDL_CFLAGS "${SDL_CFLAGS} -I/usr/include/mingw")
@ -612,15 +612,16 @@ if(USE_GCC OR USE_CLANG)
endif()
if(APPLE)
list(APPEND EXTRA_LDFLAGS "-Wl,-undefined,error")
list(APPEND EXTRA_LDFLAGS "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}")
list(APPEND EXTRA_LDFLAGS "-Wl,-current_version,${DYLIB_CURRENT_VERSION}")
# FIXME: use generator expression instead of appending to EXTRA_LDFLAGS_BUILD
list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,-undefined,error")
list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}")
list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,-current_version,${DYLIB_CURRENT_VERSION}")
elseif(NOT OPENBSD)
set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined")
check_c_compiler_flag("" HAVE_NO_UNDEFINED)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_NO_UNDEFINED AND NOT (USE_CLANG AND WINDOWS))
list(APPEND EXTRA_LDFLAGS "-Wl,--no-undefined")
list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,--no-undefined")
endif()
endif()
@ -1838,8 +1839,6 @@ elseif(WINDOWS)
file(GLOB VERSION_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.rc)
file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.c)
if(MINGW OR CYGWIN)
list(APPEND EXTRA_LIBS mingw32)
list(APPEND EXTRA_LDFLAGS "-mwindows")
list(APPEND SDL_LIBS "-lmingw32" "-mwindows")
if(NOT SDL2_DISABLE_SDL2MAIN)
set(SDL_CFLAGS "${SDL_CFLAGS} -Dmain=SDL_main")
@ -2850,7 +2849,7 @@ endif()
message(STATUS "")
message(STATUS " CFLAGS: ${CMAKE_C_FLAGS}")
message(STATUS " EXTRA_CFLAGS: ${EXTRA_CFLAGS}")
message(STATUS " EXTRA_LDFLAGS: ${EXTRA_LDFLAGS}")
message(STATUS " EXTRA_LDFLAGS: ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD}")
message(STATUS " EXTRA_LIBS: ${EXTRA_LIBS}")
message(STATUS "")
message(STATUS " Build Shared Library: ${SDL_SHARED}")
@ -2897,6 +2896,14 @@ if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
if (WIN32)
target_link_libraries(SDL2main PRIVATE shell32)
endif()
if(MINGW OR CYGWIN)
cmake_minimum_required(VERSION 3.13)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_link_options(SDL2main PUBLIC "-Wl,--undefined=_WinMain@16")
else()
target_link_options(SDL2main PUBLIC "-Wl,--undefined=WinMain")
endif()
endif()
if (NOT ANDROID)
set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
endif()
@ -2945,11 +2952,17 @@ if(SDL_SHARED)
endif()
set_target_properties(SDL2 PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB")
endif()
target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
# FIXME: if CMAKE_VERSION >= 3.13, use target_link_options for EXTRA_LDFLAGS
target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD})
target_include_directories(SDL2 BEFORE PRIVATE "${SDL2_BINARY_DIR}/include")
target_include_directories(SDL2 PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>;$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>;$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>")
# This picks up all the compiler options and such we've accumulated up to here.
target_link_libraries(SDL2 PRIVATE $<BUILD_INTERFACE:sdl-build-options>)
if(MINGW OR CYGWIN)
if(NOT CMAKE_VERSION VERSION_LESS "3.13")
target_link_options(SDL2 PRIVATE -static-libgcc)
endif()
endif()
if(NOT ANDROID)
set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
endif()
@ -2963,12 +2976,11 @@ if(SDL_STATIC)
add_library(SDL2-static STATIC ${SOURCE_FILES})
# alias target for in-tree builds
add_library(SDL2::SDL2-static ALIAS SDL2-static)
if (NOT SDL_SHARED OR NOT WIN32 OR MINGW)
if(MSVC OR (WATCOM AND (WIN32 OR OS2)))
# Avoid conflict between the dll import library and the static library
set_target_properties(SDL2-static PROPERTIES OUTPUT_NAME "SDL2-static")
else()
set_target_properties(SDL2-static PROPERTIES OUTPUT_NAME "SDL2")
# Note: Apparently, OUTPUT_NAME must really be unique; even when
# CMAKE_IMPORT_LIBRARY_SUFFIX or the like are given. Otherwise
# the static build may race with the import lib and one will get
# clobbered, when the suffix is realized via subsequent rename.
endif()
set_target_properties(SDL2-static PROPERTIES POSITION_INDEPENDENT_CODE ${SDL_STATIC_PIC})
# Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB.
@ -2979,7 +2991,7 @@ if(SDL_STATIC)
endif()
# TODO: Win32 platforms keep the same suffix .lib for import and static
# libraries - do we need to consider this?
target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD})
target_include_directories(SDL2-static BEFORE PRIVATE "${SDL2_BINARY_DIR}/include")
target_include_directories(SDL2-static PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include> $<INSTALL_INTERFACE:include/SDL2>)
# This picks up all the compiler options and such we've accumulated up to here.
@ -3047,6 +3059,10 @@ if(NOT SDL2_DISABLE_INSTALL)
endif ()
include(CMakePackageConfigHelpers)
configure_package_config_file(SDL2Config.cmake.in "${CMAKE_BINARY_DIR}/SDL2Config.cmake"
PATH_VARS CMAKE_INSTALL_PREFIX CMAKE_INSTALL_FULL_BINDIR CMAKE_INSTALL_FULL_INCLUDEDIR CMAKE_INSTALL_FULL_LIBDIR
INSTALL_DESTINATION ${PKG_PREFIX}
)
write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake"
VERSION ${SDL_VERSION}
COMPATIBILITY AnyNewerVersion
@ -3086,7 +3102,7 @@ if(NOT SDL2_DISABLE_INSTALL)
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/SDL2Config.cmake
${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake
DESTINATION ${PKG_PREFIX}
COMPONENT Devel

View file

@ -1,122 +0,0 @@
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake")
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake")
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake")
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake")
endif()
# on static-only builds create an alias
if(NOT TARGET SDL2::SDL2 AND TARGET SDL2::SDL2-static)
if(CMAKE_VERSION VERSION_LESS "3.18")
# Aliasing local targets is not supported on CMake < 3.18, so make it global.
set_target_properties(SDL2::SDL2-static PROPERTIES IMPORTED_GLOBAL TRUE)
endif()
add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static)
endif()
# provide ${SDL2_LIBRARIES}, ${SDL2_INCLUDE_DIRS} etc, like sdl2-config.cmake does,
# for compatibility between SDL2 built with autotools and SDL2 built with CMake
# the following seems to work on Windows for both MSVC and MINGW+MSYS and with both SDL2Config/Target.cmake
# from vcpkg and from building myself with cmake from latest git
# AND on Linux when building SDL2 (tested current git) with CMake
# the headers are easy - but note that this adds both .../include/ and .../include/SDL2/
# while the SDL2_INCLUDE_DIRS of sdl2-config.cmake only add ...include/SDL2/
# But at least if building worked with sdl2-config.cmake it will also work with this.
get_target_property(SDL2_INCLUDE_DIRS SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES)
# get the paths to the files to link against (.lib or .dll.a on Windows, .so or .a on Unix, ...) for both SDL2 and SDL2main
# for the "normal"/release build they could be in lots of different properties..
set(relprops IMPORTED_IMPLIB_RELEASE IMPORTED_IMPLIB_NOCONFIG IMPORTED_IMPLIB IMPORTED_IMPLIB_MINSIZEREL IMPORTED_IMPLIB_RELWITHDEBINFO
IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION_NOCONFIG IMPORTED_LOCATION IMPORTED_LOCATION_MINSIZEREL IMPORTED_LOCATION_RELWITHDEBINFO)
# fewer possibilities for debug builds
set(dbgprops IMPORTED_IMPLIB_DEBUG IMPORTED_LOCATION_DEBUG)
foreach(prop ${relprops})
get_target_property(sdl2implib SDL2::SDL2 ${prop})
if(sdl2implib)
#message("set sdl2implib from ${prop}")
break()
endif()
endforeach()
foreach(prop ${relprops})
get_target_property(sdl2mainimplib SDL2::SDL2main ${prop})
if(sdl2mainimplib)
#message("set sdl2mainimplib from ${prop}")
break()
endif()
endforeach()
foreach(prop ${dbgprops})
get_target_property(sdl2implibdbg SDL2::SDL2 ${prop})
if(sdl2implibdbg)
#message("set sdl2implibdbg from ${prop}")
break()
endif()
endforeach()
foreach(prop ${dbgprops})
get_target_property(sdl2mainimplibdbg SDL2::SDL2main ${prop})
if(sdl2mainimplibdbg)
#message("set sdl2mainimplibdbg from ${prop}")
break()
endif()
endforeach()
if( sdl2implib AND sdl2mainimplib AND sdl2implibdbg AND sdl2mainimplibdbg )
# we have both release and debug builds of SDL2 and SDL2main, so use this ugly
# generator expression in SDL2_LIBRARIES to support both in MSVC, depending on build type configured there
set(SDL2_LIBRARIES $<IF:$<CONFIG:Debug>,${sdl2mainimplibdbg},${sdl2mainimplib}> $<IF:$<CONFIG:Debug>,${sdl2implibdbg},${sdl2implib}>)
else()
if( (NOT sdl2implib) AND sdl2implibdbg ) # if we only have a debug version of the lib
set(sdl2implib ${sdl2implibdbg})
endif()
if( (NOT sdl2mainimplib) AND sdl2mainimplibdbg ) # if we only have a debug version of the lib
set(sdl2mainimplib ${sdl2mainimplibdbg})
endif()
if( sdl2implib AND sdl2mainimplib )
set(SDL2_LIBRARIES ${sdl2mainimplib} ${sdl2implib})
elseif(WIN32 OR APPLE) # I think these platforms have a non-dummy SDLmain?
message(FATAL_ERROR, "SDL2::SDL2 and/or SDL2::SDL2main don't seem to contain any kind of IMPORTED_IMPLIB* or IMPORTED_LOCATION*")
elseif(sdl2implib) # on other platforms just libSDL2 will hopefully do?
set(SDL2_LIBRARIES ${sdl2implib})
message(STATUS, "No SDL2main lib not found, I hope you don't need it..")
else()
message(FATAL_ERROR, "SDL2::SDL2 doesn't seem to contain any kind of lib to link against in IMPORTED_IMPLIB* or IMPORTED_LOCATION*")
endif()
# TODO: should something like INTERFACE_LINK_LIBRARIES be appended? or wherever -mwindows and things like that
# might be defined (if they were defined by the CMake build at all; autotools has @SDL_RLD_FLAGS@ @SDL_LIBS@)?
# LINK_DEPENDS? LINK_FLAGS?
endif()
get_filename_component(SDL2_LIBDIR ${sdl2implib} PATH)
# NOTE: SDL2_LIBRARIES now looks like "c:/path/to/SDL2main.lib;c:/path/to/SDL2.lib"
# which is different to what it looks like when coming from sdl2-config.cmake
# (there it's more like "-L${SDL2_LIBDIR} -lSDL2main -lSDL2" - and also -lmingw32 and -mwindows)
# This seems to work with both MSVC and MinGW though, while the other only worked with MinGW
# On Linux it looks like "/tmp/sdl2inst/lib/libSDL2main.a;/tmp/sdl2inst/lib/libSDL2-2.0.so.0.14.1" which also seems to work
# the exec prefix is one level up from lib/ - TODO: really, always? at least on Linux there's /usr/lib/x86_64-bla-blub/libSDL2-asdf.so.0 ..
get_filename_component(SDL2_EXEC_PREFIX ${SDL2_LIBDIR} PATH)
set(SDL2_PREFIX ${SDL2_EXEC_PREFIX}) # TODO: could this be somewhere else? parent dir of include or sth?
unset(sdl2implib)
unset(sdl2mainimplib)
unset(sdl2implibdbg)
unset(sdl2mainimplibdbg)
unset(relprops)
unset(dbgprops)

60
SDL2Config.cmake.in Normal file
View file

@ -0,0 +1,60 @@
# sdl2 cmake project-config input for CMakeLists.txt script
include(FeatureSummary)
set_package_properties(SDL2 PROPERTIES
URL "https://www.libsdl.org/"
DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware"
)
@PACKAGE_INIT@
set(SDL2_FOUND TRUE)
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake")
set(SDL2_SDL2_FOUND TRUE)
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake")
set(SDL2_SDL2-static_FOUND TRUE)
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake")
set(SDL2_SDL2main_FOUND TRUE)
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake")
set(SDL2_SDL2test_FOUND TRUE)
endif()
check_required_components(SDL2)
# Create SDL2::SDL2 alias for static-only builds
if(NOT TARGET SDL2::SDL2 AND TARGET SDL2::SDL2-static)
if(CMAKE_VERSION VERSION_LESS "3.18")
# Aliasing local targets is not supported on CMake < 3.18, so make it global.
set_target_properties(SDL2::SDL2-static PROPERTIES IMPORTED_GLOBAL TRUE)
endif()
add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static)
endif()
# For compatibility with autotools sdl2-config.cmake, provide SDL2_* variables.
set(SDL2_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@")
set(SDL2_EXEC_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@")
set(SDL2_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2")
set(SDL2_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@;@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2")
set(SDL2_BINDIR "@PACKAGE_CMAKE_INSTALL_FULL_BINDIR@")
set(SDL2_LIBDIR "@PACKAGE_CMAKE_INSTALL_FULL_LIBDIR@")
set(SDL2_LIBRARIES SDL2::SDL2)
set(SDL2_STATIC_LIBRARIES SDL2::SDL2-static)
set(SDL2_STATIC_PRIVATE_LIBS)
set(SDL2MAIN_LIBRARY)
if(TARGET SDL2::SDL2main)
set(SDL2MAIN_LIBRARY SDL2::SDL2main)
list(INSERT SDL2_LIBRARIES 0 SDL2::SDL2main)
list(INSERT SDL2_STATIC_LIBRARIES 0 SDL2::SDL2main)
endif()
set(SDL2TEST_LIBRARY SDL2::SDL2test)