SDL: cmake: SDL3-shared target will always be a shared target

From dc138ee3d4d3f9a0128a541c02172a8faedbb746 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Thu, 16 Feb 2023 23:30:20 +0100
Subject: [PATCH] cmake: SDL3-shared target will always be a shared target

---
 .github/workflows/haiku.yml |  2 ++
 CMakeLists.txt              | 63 +++++++++++++++++++------------------
 cmake/SDL3Config.cmake.in   | 30 ++++++++++++------
 cmake/test/CMakeLists.txt   | 18 ++++++-----
 docs/README-cmake.md        | 38 ++++++++++------------
 test/CMakeLists.txt         |  2 +-
 6 files changed, 83 insertions(+), 70 deletions(-)

diff --git a/.github/workflows/haiku.yml b/.github/workflows/haiku.yml
index 7729876f3d56..4bd57ca31f9f 100644
--- a/.github/workflows/haiku.yml
+++ b/.github/workflows/haiku.yml
@@ -33,6 +33,8 @@ jobs:
       run: |
         vmshell cmake -S src -B build -GNinja \
           -Wdeprecated -Wdev -Werror \
+          -DSDL_SHARED=ON \
+          -DSDL_STATIC=ON \
           -DSDL_TESTS=ON \
           -DSDL_WERROR=ON \
           -DSDL_INSTALL_TESTS=ON \
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f688ff299e4..e3e12914b5c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3166,15 +3166,16 @@ else()
 endif()
 
 if(SDL_SHARED)
-  add_library(SDL3 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
-  add_library(SDL3::SDL3 ALIAS SDL3)
-  set_target_properties(SDL3 PROPERTIES
+  add_library(SDL3-shared SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
+  add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
+  set_target_properties(SDL3-shared PROPERTIES
+    OUTPUT_NAME "SDL3"
     POSITION_INDEPENDENT_CODE TRUE
     LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym"
     INTERFACE_LINK_DEPENDS "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym>"
   )
   if(HAVE_GCC_FVISIBILITY)
-    set_target_properties(SDL3 PROPERTIES
+    set_target_properties(SDL3-shared PROPERTIES
       C_VISIBILITY_PRESET "hidden"
       CXX_VISIBILITY_PRESET "hidden"
       OBJC_VISIBILITY_PRESET "hidden"
@@ -3183,16 +3184,16 @@ if(SDL_SHARED)
   if(NOT SDL_LIBC)
     if(MSVC AND SDL_CPU_X86)
       # FIXME: should be added for all architectures (missing symbols for ARM)
-      target_link_libraries(SDL3 PRIVATE "-nodefaultlib:MSVCRT")
+      target_link_libraries(SDL3-shared PRIVATE "-nodefaultlib:MSVCRT")
     endif()
   endif()
   if(APPLE)
-    set_target_properties(SDL3 PROPERTIES
+    set_target_properties(SDL3-shared PROPERTIES
       MACOSX_RPATH TRUE
       FRAMEWORK "${SDL_FRAMEWORK}"
     )
     if(SDL_FRAMEWORK)
-      set_target_properties(SDL3 PROPERTIES
+      set_target_properties(SDL3-shared PROPERTIES
         PUBLIC_HEADER "${SDL3_INCLUDE_FILES}"
         FRAMEWORK_VERSION "${SDL_FRAMEWORK_VERSION}"
         MACOSX_FRAMEWORK_IDENTIFIER "org.libsdl.SDL3"
@@ -3200,18 +3201,18 @@ if(SDL_SHARED)
       )
     endif()
     if(NOT CMAKE_VERSION VERSION_LESS "3.6")
-      set_target_properties(SDL3 PROPERTIES
+      set_target_properties(SDL3-shared PROPERTIES
         SOVERSION "${SDL_DYLIB_COMPAT_VERSION}" # SOVERSION corresponds to compatibility version
         VERSION "${SDL_DYLIB_CURRENT_VERSION}"  # VERSION corresponds to the current version
       )
     endif()
   elseif(UNIX AND NOT ANDROID)
-    set_target_properties(SDL3 PROPERTIES
+    set_target_properties(SDL3-shared PROPERTIES
       VERSION "${SDL_SO_VERSION}"
       SOVERSION "${SDL_SO_VERSION_MAJOR}")
   else()
     if(WINDOWS OR CYGWIN)
-      set_target_properties(SDL3 PROPERTIES
+      set_target_properties(SDL3-shared PROPERTIES
         DEFINE_SYMBOL DLL_EXPORT)
     endif()
   endif()
@@ -3219,33 +3220,33 @@ if(SDL_SHARED)
   if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
     # Don't try to link with the default set of libraries.
     if(NOT WINDOWS_STORE)
-      set_target_properties(SDL3 PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB")
-      set_target_properties(SDL3 PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB")
+      set_target_properties(SDL3-shared PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB")
+      set_target_properties(SDL3-shared PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB")
     endif()
-    set_target_properties(SDL3 PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB")
+    set_target_properties(SDL3-shared PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB")
   endif()
   # FIXME: if CMAKE_VERSION >= 3.13, use target_link_options for SDL_EXTRA_LDFLAGS
-  target_link_libraries(SDL3 PRIVATE ${SDL_EXTRA_LIBS} ${SDL_EXTRA_LDFLAGS} ${SDL_CMAKE_DEPENDS})
-  target_include_directories(SDL3
+  target_link_libraries(SDL3-shared PRIVATE ${SDL_EXTRA_LIBS} ${SDL_EXTRA_LDFLAGS} ${SDL_CMAKE_DEPENDS})
+  target_include_directories(SDL3-shared
     PRIVATE
       "$<BUILD_INTERFACE:${SDL3_BINARY_DIR}/include-config-$<LOWER_CASE:$<CONFIG>>>"
       "$<BUILD_INTERFACE:${SDL3_SOURCE_DIR}/src>"
   )
-  target_link_libraries(SDL3 PUBLIC $<TARGET_NAME:SDL3::Headers>)
+  target_link_libraries(SDL3-shared PUBLIC $<TARGET_NAME:SDL3::Headers>)
   # This picks up all the compiler options and such we've accumulated up to here.
-  target_link_libraries(SDL3 PRIVATE $<${build_local_interface}:sdl-build-options>)
-  target_link_libraries(SDL3 PRIVATE $<${build_local_interface}:sdl-shared-build-options>)
-  target_link_libraries(SDL3 PRIVATE $<${build_local_interface}:sdl-global-options>)
+  target_link_libraries(SDL3-shared PRIVATE $<${build_local_interface}:sdl-build-options>)
+  target_link_libraries(SDL3-shared PRIVATE $<${build_local_interface}:sdl-shared-build-options>)
+  target_link_libraries(SDL3-shared PRIVATE $<${build_local_interface}:sdl-global-options>)
   if(MINGW OR CYGWIN)
     if(NOT CMAKE_VERSION VERSION_LESS "3.13")
-      target_link_options(SDL3 PRIVATE -static-libgcc)
+      target_link_options(SDL3-shared PRIVATE -static-libgcc)
     endif()
   endif()
   # Use `Compatible Interface Properties` to allow consumers to enforce a shared/static library
-  set_property(TARGET SDL3 PROPERTY INTERFACE_SDL3_SHARED TRUE)
-  set_property(TARGET SDL3 APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL3_SHARED)
+  set_property(TARGET SDL3-shared PROPERTY INTERFACE_SDL3_SHARED TRUE)
+  set_property(TARGET SDL3-shared APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL3_SHARED)
   if(NOT CMAKE_VERSION VERSION_LESS "3.16")
-    target_precompile_headers(SDL3 PRIVATE "${PROJECT_SOURCE_DIR}/src/SDL_internal.h")
+    target_precompile_headers(SDL3-shared PRIVATE "${PROJECT_SOURCE_DIR}/src/SDL_internal.h")
   endif()
 endif()
 
@@ -3300,8 +3301,6 @@ if(SDL_TEST)
   add_library(SDL3_test STATIC ${TEST_SOURCES})
   add_library(SDL3::SDL3_test ALIAS SDL3_test)
   target_link_libraries(SDL3_test PRIVATE $<${build_local_interface}:sdl-global-options>)
-  set_target_properties(SDL3_test PROPERTIES
-      EXPORT_NAME SDL3_test)
   if(APPLE)
     set_target_properties(SDL3_test PROPERTIES
       FRAMEWORK "${SDL_FRAMEWORK}"
@@ -3383,12 +3382,12 @@ else()
   endif()
 
 if(CMAKE_VERSION VERSION_LESS "3.26")
-  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/SDL3Targets.cmake" [[message(FATAL_ERROR "find_package(SDL3) using the SDL3 build directory not supported for CMake versions older then 3.26.")]])
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/SDL3sharedTargets.cmake" [[message(FATAL_ERROR "find_package(SDL3) using the SDL3 build directory not supported for CMake versions older then 3.26.")]])
 else()
   export(TARGETS SDL3_Headers NAMESPACE "SDL3::" FILE "SDL3headersTargets.cmake")
 
   if(SDL_SHARED)
-    export(TARGETS SDL3 NAMESPACE "SDL3::" FILE "SDL3Targets.cmake")
+    export(TARGETS SDL3-shared NAMESPACE "SDL3::" FILE "SDL3sharedTargets.cmake")
   endif()
 
   if(SDL_STATIC)
@@ -3457,7 +3456,7 @@ if(NOT SDL_DISABLE_INSTALL)
   install(TARGETS SDL3_Headers EXPORT SDL3headersTargets)
 
   if(SDL_SHARED)
-    install(TARGETS SDL3 EXPORT SDL3Targets
+    install(TARGETS SDL3-shared EXPORT SDL3sharedTargets
       PUBLIC_HEADER DESTINATION "${SDL_INSTALL_HEADERSDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
@@ -3492,8 +3491,8 @@ if(NOT SDL_DISABLE_INSTALL)
   )
 
   if(SDL_SHARED)
-    install(EXPORT SDL3Targets
-      FILE "SDL3Targets.cmake"
+    install(EXPORT SDL3sharedTargets
+      FILE "SDL3sharedTargets.cmake"
       NAMESPACE SDL3::
       DESTINATION "${SDL_SDL_INSTALL_CMAKEDIR}"
     )
@@ -3575,6 +3574,8 @@ endif()
 set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${CMAKE_C_FLAGS}")
 
 # Make sure SDL3::SDL3 always exists
-if(TARGET SDL3::SDL3-static AND NOT TARGET SDL3::SDL3)
+if(TARGET SDL3::SDL3-shared)
+  add_library(SDL3::SDL3 ALIAS SDL3-shared)
+else()
   add_library(SDL3::SDL3 ALIAS SDL3-static)
 endif()
diff --git a/cmake/SDL3Config.cmake.in b/cmake/SDL3Config.cmake.in
index 27ebd5a1da1c..b1dbdadc9e72 100644
--- a/cmake/SDL3Config.cmake.in
+++ b/cmake/SDL3Config.cmake.in
@@ -17,10 +17,10 @@ if(NOT TARGET SDL3::Headers)
 endif()
 set(SDL3_Headers_FOUND TRUE)
 
-# Find SDL3::SDL3
-if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL3Targets.cmake")
-  include("${CMAKE_CURRENT_LIST_DIR}/SDL3Targets.cmake")
-  set(SDL3_SDL3_FOUND TRUE)
+# Find SDL3::SDL3-shared
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL3sharedTargets.cmake")
+  include("${CMAKE_CURRENT_LIST_DIR}/SDL3sharedTargets.cmake")
+  set(SDL3_SDL3-shared_FOUND TRUE)
 endif()
 
 # Find SDL3::SDL3-static
@@ -39,6 +39,10 @@ else()
   endif()
 endif()
 
+if(SDL3_SDL3-shared_FOUND OR SDL3_SDL3-static_FOUND)
+  set(SDL3_SDL3_FOUND TRUE)
+endif()
+
 # Find SDL3::SDL3_test
 if(_sdl3_framework)
   find_package(SDL3_test CONFIG)
@@ -65,14 +69,22 @@ unset(SDL_ALSA_SHARED)
 
 check_required_components(SDL3)
 
-# Create SDL3::SDL3 alias for static-only builds
-if(TARGET SDL3::SDL3-static AND NOT TARGET SDL3::SDL3)
+function(_sdl_create_target_alias_compat NEW_TARGET TARGET)
   if(CMAKE_VERSION VERSION_LESS "3.18")
     # FIXME: Aliasing local targets is not supported on CMake < 3.18, so make it global.
-    add_library(SDL3::SDL3 INTERFACE IMPORTED)
-    set_target_properties(SDL3::SDL3 PROPERTIES INTERFACE_LINK_LIBRARIES "SDL3::SDL3-static")
+    add_library(${NEW_TARGET} INTERFACE IMPORTED)
+    set_target_properties(${NEW_TARGET} PROPERTIES INTERFACE_LINK_LIBRARIES "${TARGET}")
+  else()
+    add_library(${NEW_TARGET} ALIAS ${TARGET})
+  endif()
+endfunction()
+
+# Make sure SDL3::SDL3 always exists
+if(NOT TARGET SDL3::SDL3)
+  if(TARGET SDL3::SDL3-shared)
+    _sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-shared)
   else()
-    add_library(SDL3::SDL3 ALIAS SDL3::SDL3-static)
+    _sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-static)
   endif()
 endif()
 
diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt
index ce58467ecc31..da7c1505457d 100644
--- a/cmake/test/CMakeLists.txt
+++ b/cmake/test/CMakeLists.txt
@@ -35,32 +35,32 @@ add_library(headers_test OBJECT inc_sdl_slash.c inc_sdl_noslash.c)
 target_link_libraries(headers_test PRIVATE SDL3::Headers)
 
 if(TEST_SHARED)
-    find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3)
+    find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3-shared)
     add_executable(gui-shared WIN32 main_gui.c)
-    target_link_libraries(gui-shared PRIVATE SDL3::SDL3)
+    target_link_libraries(gui-shared PRIVATE SDL3::SDL3-shared)
     if(WIN32)
         add_custom_command(TARGET gui-shared POST_BUILD
-            COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:SDL3::SDL3>" "$<TARGET_FILE_DIR:gui-shared>"
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:SDL3::SDL3-shared>" "$<TARGET_FILE_DIR:gui-shared>"
         )
     endif()
 
     add_library(sharedlib-shared SHARED main_lib.c)
-    target_link_libraries(sharedlib-shared PRIVATE SDL3::SDL3)
+    target_link_libraries(sharedlib-shared PRIVATE SDL3::SDL3-shared)
     generate_export_header(sharedlib-shared EXPORT_MACRO_NAME MYLIBRARY_EXPORT)
     target_compile_definitions(sharedlib-shared PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared_export.h\"")
     set_target_properties(sharedlib-shared PROPERTIES C_VISIBILITY_PRESET "hidden")
 
     add_executable(cli-shared main_cli.c)
-    target_link_libraries(cli-shared PRIVATE SDL3::SDL3)
+    target_link_libraries(cli-shared PRIVATE SDL3::SDL3-shared)
     if(WIN32)
         add_custom_command(TARGET cli-shared POST_BUILD
-            COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:SDL3::SDL3>" "$<TARGET_FILE_DIR:cli-shared>"
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:SDL3::SDL3-shared>" "$<TARGET_FILE_DIR:cli-shared>"
         )
     endif()
 
     if(TEST_TEST)
         add_executable(sdltest-shared sdltest.c)
-        target_link_libraries(sdltest-shared PRIVATE SDL3::SDL3_test SDL3::SDL3)
+        target_link_libraries(sdltest-shared PRIVATE SDL3::SDL3_test SDL3::SDL3-shared)
     endif()
 endif()
 
@@ -84,4 +84,8 @@ if(TEST_STATIC)
     endif()
 endif()
 
+find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3)
+add_executable(gui-whatever WIN32 main_gui.c)
+target_link_libraries(gui-whatever PRIVATE SDL3::SDL3)
+
 feature_summary(WHAT ALL)
diff --git a/docs/README-cmake.md b/docs/README-cmake.md
index 66b52e514a8d..39787b5f9c38 100644
--- a/docs/README-cmake.md
+++ b/docs/README-cmake.md
@@ -2,13 +2,6 @@
 
 (www.cmake.org)
 
-SDL's build system was traditionally based on autotools. Over time, this
-approach has suffered from several issues across the different supported 
-platforms.
-To solve these problems, a new build system based on CMake was introduced.
-It is developed in parallel to the legacy autotools build system, so users 
-can experiment with it without complication.
-
 The CMake build system is supported on the following platforms:
 
 * FreeBSD
@@ -19,26 +12,27 @@ The CMake build system is supported on the following platforms:
 * Android
 * Emscripten
 * RiscOS
+* Playstation 2
 * Playstation Vita
+* Nintendo 3DS
 
 ## Building SDL
 
-Assuming the source for SDL is located at `~/sdl`
+Assuming the source for SDL is located at `~/sdl`. 
 ```sh
-cd ~
-mkdir build
-cd build
-cmake ~/sdl
-cmake --build .
+cmake -S ~/sdl -B ~/build
+cmake --build ~/build

-This will build the static and dynamic versions of SDL in the ~/build directory.
+This will build SDL in the ~/build directory.
Installation can be done using:

-cmake --install .        # '--install' requires CMake 3.15, or newer
+cmake --install ~/build --prefix /usr/local        # '--install' requires CMake 3.15, or newer

+This will install SDL to /usr/local.
+

Including SDL in your project

SDL can be included in your project in 2 major ways:
@@ -74,11 +68,13 @@ For CMake to find SDL, it must be installed in [a default location CMake is look

The following components are available, to be used as an argument of find_package.

- Component name Description
- SDL3 The SDL3 shared library, available through the SDL3::SDL3 target [^SDL_TARGET_EXCEPTION]
- SDL3-static The SDL3 static library, available through the SDL3::SDL3-static target
- SDL3_test The SDL3_test static library, available through the SDL3::SDL3_test target
+ Component name Description
+ ---------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------
+ SDL3-shared The SDL3 shared library, available through the SDL3::SDL3-shared target
+ SDL3-static The SDL3 static library, available through the SDL3::SDL3-static target
+ SDL3_test The SDL3_test static library, available through the SDL3::SDL3_test target
+ SDL3 The SDL3 library, available through the SDL3::SDL3 target. This is an alias of SDL3::SDL3 or SDL3::SDL3-static. This component is always available.
+ Headers The SDL3 headers, available through the SDL3::Headers target. This component is always available.

Using a vendored SDL

@@ -150,5 +146,3 @@ To use, set the following CMake variables when running CMake’s configuration sta
cmake ~/sdl -DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_ARCHITECTURES=arm64`
```

-[^SDL_TARGET_EXCEPTION]: SDL3::SDL3 can be an ALIAS to a static SDL3::SDL3-static target for multiple reasons.
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0aecc33aa495…cb9e7ef8829d 100644
— a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -21,7 +21,7 @@ option(SDL_TESTS_LINK_SHARED “link tests to shared SDL library” ${SDL_TESTS_LINK
set(SDL_TESTS_TIMEOUT_MULTIPLIER “1” CACHE STRING “Timeout multiplier to account for really slow machines”)

if(SDL_TESTS_LINK_SHARED)

  • set(sdl_name_component SDL3)
  • set(sdl_name_component SDL3-shared)
    else()
    set(sdl_name_component SDL3-static)
    endif()