diff --git a/SDL2Config.cmake b/SDL2Config.cmake index fd22ffdf6..abe85e702 100644 --- a/SDL2Config.cmake +++ b/SDL2Config.cmake @@ -1,96 +1,127 @@ include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") +# provide ${SDL2_LIBRARIES}, ${SDL2_INCLUDE_DIRS} etc, like sdl2-config.cmake does, +# for compatibility between SDL2 built with autotools and SDL2 built with CMake -# cuts off the path at the last (back)slash -function(my_dirname FILEPATH RETVAL) - string(FIND ${FILEPATH} "/" slashPos REVERSE) - string(FIND ${FILEPATH} "\\" bsPos REVERSE) # TODO: untested, cmake always gave me forward slashes - if(DEFINED slashPos) - if( (DEFINED bsPos) AND (${bsPos} GREATER ${slashPos}) ) - set(slashPos, ${bsPos}) - endif() - elseif(DEFINED bsPos) - set(slashPos, ${bsPos}) - endif() - if(DEFINED slashPos) - string(SUBSTRING ${FILEPATH} 0 ${slashPos} dirname) - set(${RETVAL} ${dirname} PARENT_SCOPE) - endif() -endfunction() +# 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) -if(WIN32) - # this seems to work for both MSVC and MINGW+MSYS and with both SDL2Config/Target.cmake from vcpkg - # and from building myself with cmake from latest git +# get the paths to the .lib files for both SDL2 and SDL2main - # ok, 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) +# 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) - # get the paths to the .lib files for both SDL2 and SDL2main - # they could be in lots of different properties.. - get_target_property(sdl2implib SDL2::SDL2 IMPORTED_IMPLIB_RELEASE) - get_target_property(sdl2implibdbg SDL2::SDL2 IMPORTED_IMPLIB_DEBUG) +# fewer possibilities for debug builds +set(dbgprops IMPORTED_IMPLIB_DEBUG IMPORTED_LOCATION_DEBUG) - # TODO: for all this bla_RELEASE bla_DEBUG etc stuff, maybe only try the ones - # from get_target_property(available_configs SDL2::SDL2 IMPORTED_CONFIGURATIONS) ? - # OR otherwise at least try all of NOCONFIG, RELEASE, MINSIZEREL, RELWITHDEBINFO, DEBUG (possibly in that order)? - - get_target_property(sdl2mainimplib SDL2::SDL2main IMPORTED_IMPLIB_RELEASE) - if(NOT sdl2mainimplib) - get_target_property(sdl2mainimplib SDL2::SDL2main IMPORTED_LOCATION_RELEASE) - endif() - get_target_property(sdl2mainimplibdbg SDL2::SDL2main IMPORTED_IMPLIB_DEBUG) - if(NOT sdl2mainimplibdbg) - get_target_property(sdl2mainimplibdbg SDL2::SDL2main IMPORTED_LOCATION_DEBUG) - endif() - - 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 $,${sdl2mainimplibdbg},${sdl2mainimplib}> $,${sdl2implibdbg},${sdl2implib}>) +foreach(prop ${relprops}) + get_target_property(sdl2implib SDL2::SDL2 ${prop}) + if(sdl2implib) + #message("set sdl2implib from ${prop}") + break() else() - if(NOT sdl2implib) # try to get it from other properties - foreach(prop IMPORTED_IMPLIB IMPORTED_IMPLIB_NOCONFIG IMPORTED_IMPLIB_DEBUG IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION_DEBUG) - get_target_property(sdl2implib SDL2::SDL2 ${prop}) - if(sdl2implib) - message(STATUS "succeeded with ${prop} => ${sdl2implib}") - break() - endif() - message(STATUS "no luck with ${prop}") - endforeach() - endif() - if(NOT sdl2mainimplib) - foreach(prop IMPORTED_IMPLIB IMPORTED_IMPLIB_NOCONFIG IMPORTED_IMPLIB_DEBUG IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION_DEBUG) - get_target_property(sdl2mainimplib SDL2::SDL2main ${prop}) - if(sdl2mainimplib) - message(STATUS "succeeded with ${prop} => ${sdl2mainimplib}") - break() - endif() - message(STATUS "no luck with ${prop}") - endforeach() - endif() - - if( sdl2implib AND sdl2mainimplib ) - set(SDL2_LIBRARIES ${sdl2mainimplib} ${sdl2implib}) - else() - message(FATAL_ERROR, "SDL2::SDL2 and/or SDL2::SDL2main don't seem to contain any kind of IMPORTED_IMPLIB") - endif() + #message("no luck for sdl2implib with ${prop}") + endif() +endforeach() + +foreach(prop ${relprops}) + get_target_property(sdl2mainimplib SDL2::SDL2main ${prop}) + if(sdl2mainimplib) + #message("set sdl2mainimplib from ${prop}") + break() + else() + #message("no luck for sdl2mainimplib with ${prop}") + endif() +endforeach() + +foreach(prop ${dbgprops}) + get_target_property(sdl2implibdbg SDL2::SDL2 ${prop}) + if(sdl2implibdbg) + #message("set sdl2implibdbg from ${prop}") + break() + else() + #message("no luck for sdl2implibdbg with ${prop}") + endif() +endforeach() + +foreach(prop ${dbgprops}) + get_target_property(sdl2mainimplibdbg SDL2::SDL2main ${prop}) + if(sdl2mainimplibdbg) + #message("set sdl2mainimplibdbg from ${prop}") + break() + else() + #message("no luck for sdl2mainimplibdbg with ${prop}") + 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 $,${sdl2mainimplibdbg},${sdl2mainimplib}> $,${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() - # 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 - - my_dirname(${sdl2implib} SDL2_LIBDIR) - - my_dirname(${SDL2_LIBDIR} SDL2_EXEC_PREFIX) # 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 .. - set(SDL2_PREFIX ${SDL2_PREFIX}) # TODO: could this be somewhere else? parent dir of include or sth? - -elseif() # not windows - # TODO: about the same but don't have to look at *_IMPLIB* as that's windows specific, it should be in IMPORTED_LOCATION* - # TODO: make SDL2_LIBRARIES look more like the original (instead of path to libSDL2.so)? - # TODO: anything special about macOS? I can't test that, I have no Mac + 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() 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 +# We *could* use if(MSVC) here and make the MinGW case oldschool, BUT keep in mind that +# for some reason vcpkg has SDL2.lib and SDL2main.lib in different directories! +# 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 + +if(FALSE) # this (not tested much) could be used to make SDL2_LIBRARIES look/behave more like the original from sdl2-config.cmake +#if(NOT MSVC) # this is GCC/ld syntax (should also work for mingw and clang), not suitable for MSVC + + if(sdl2mainimplib) # we have libSDL2main + # first set libSDL2main and its directory + get_filename_component(sdl2main_libdir ${sdl2mainimplib} PATH) + set(SDL2_LIBRARIES "-L${sdl2main_libdir} -lSDL2main") + # SDL2main can be in a different directory than libSDL2 itself, at least when using vcpkg + # if that's the case, add an additional "-L" part for libSDL2's libdir + if( NOT (sdl2main_libdir STREQUAL SDL2_LIBDIR) ) + set(SDL2_LIBRARIES "${SDL2_LIBRARIES} -L${SDL2_LIBDIR}") + endif() + # lastly, add -lSDL2 itself + set(SDL2_LIBRARIES "${SDL2_LIBRARIES} -lSDL2") + unset(sdl2main_libdir) + else() # no SDL2main, just libSDL2 itself + set(SDL2_LIBRARIES "-L${SDL2_LIBDIR} -lSDL2") + endif() +endif() + +# 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)