SDL_image: Add missing options to cmake script

From f9a635c538f16395ee32f9c0cc38ecb48215a58f Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 9 May 2022 15:34:10 +0200
Subject: [PATCH] Add missing options to cmake script

---
 .github/workflows/main.yml |   1 +
 CMakeLists.txt             | 669 ++++++++++++++++++++++++++++---------
 SDL2_image-config.cmake.in |  56 ++++
 test-versioning.sh         |   9 +-
 4 files changed, 584 insertions(+), 151 deletions(-)
 create mode 100644 SDL2_image-config.cmake.in

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c8c64fa..717a112 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -73,6 +73,7 @@ jobs:
           -DBUILD_SHOWIMAGE=ON \
           -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
           -DCMAKE_VERBOSE_MAKEFILE=ON \
+          -DSUPPORT_JXL=OFF \
           -DSUPPORT_WEBP=ON \
           ${{ matrix.platform.cmake }}
     - name: Build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5ff08f..d0e8c28 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,45 +1,21 @@
-# FIXME: CMAKE SUPPORT IN SDL2_image IS VERY INCOMPLETE YET !!!
-#
-# FIXME: make it able build against system codec libraries, too.
-# FIXME: handle library versioning.
-# FIXME: test accross different target platforms.
-#
-
 cmake_minimum_required(VERSION 3.3.2)
-project(SDL_image C)
 
 # See docs/release_checklist.md
 set(MAJOR_VERSION 2)
 set(MINOR_VERSION 5)
 set(MICRO_VERSION 0)
 set(FULL_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}")
-
-if (NOT ANDROID AND NOT (TARGET SDL2 OR TARGET SDL2-static))
-	find_package(SDL2 REQUIRED)
-endif()
-
-# Workaround for Ubuntu 20.04's SDL being older than
-# https://github.com/libsdl-org/SDL/issues/3531
-if (NOT TARGET SDL2::SDL2)
-	add_library(SDL2::SDL2 SHARED IMPORTED)
-	find_library(SDL2_LIBRARY
-		NAMES SDL2
-		HINTS "${SDL2_EXEC_PREFIX}"
-		REQUIRED)
-	set_target_properties(SDL2::SDL2 PROPERTIES
-		INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
-		IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-		IMPORTED_LOCATION "${SDL2_LIBRARY}")
-endif()
+set(SDL_REQUIRED_VERSION 2.0.8)
 
 # Calculate a libtool-like version number
 math(EXPR BINARY_AGE "${MINOR_VERSION} * 100 + ${MICRO_VERSION}")
-if(MINOR_VERSION MATCHES "[02468]$")
-    # Stable branch, 2.6.1 -> libSDL2_image-2.0.so.0.600.1
-    set(INTERFACE_AGE ${MICRO_VERSION})
-else()
+math(EXPR SDL2_IMAGE_DEVELOPMENT "${MINOR_VERSION} % 2")
+if (SDL2_IMAGE_DEVELOPMENT)
     # Development branch, 2.5.1 -> libSDL2_image-2.0.so.0.501.0
     set(INTERFACE_AGE 0)
+else()
+    # Stable branch, 2.6.1 -> libSDL2_image-2.0.so.0.600.1
+    set(INTERFACE_AGE ${MICRO_VERSION})
 endif()
 
 # Increment this if there is an incompatible change - but if that happens,
@@ -68,169 +44,562 @@ set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSIO
 # For historical reasons this is 3.0.0 rather than the expected 1.0.0
 set(DYLIB_COMPATIBILITY_VERSION "3.0.0")
 
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION}")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MINOR_VERSION=${MINOR_VERSION}")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MICRO_VERSION=${MICRO_VERSION}")
+project(SDL2_image LANGUAGES C
+    VERSION "${FULL_VERSION}")
+
+message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}")
+
+if (NOT ANDROID AND NOT (TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static))
+    find_package(SDL2 REQUIRED)
+endif()
+
+function(read_absolute_symlink DEST PATH)
+    file(READ_SYMLINK "${PATH}" p)
+    if (NOT IS_ABSOLUTE p)
+        get_filename_component(pdir "${PATH}" DIRECTORY)
+        set(p "${pdir}/${p}")
+    endif()
+    set("${DEST}" "${p}" PARENT_SCOPE)
+endfunction()
+
+function(target_get_dynamic_library DEST TARGET)
+    set(result)
+    if (NOT result)
+        get_target_property(result "${TARGET}" IMPORTED_LOCATION)
+        while (IS_SYMLINK "${result}" AND NOT result MATCHES ".*[0-9]$")
+            read_absolute_symlink(result "${result}")
+        endwhile()
+        get_filename_component(result "${result}" NAME)
+    endif()
+    if (NOT result)
+        set (result "$<TARGET_FILE_NAME:${TARGET}>")
+    endif()
+    if(NOT result)
+        message(FATAL_ERROR "Don't know how to read symlink for this target type")
+    endif()
+    set(${DEST} ${result} PARENT_SCOPE)
+endfunction()
+
+# Workaround for Ubuntu 20.04's SDL being older than
+# https://github.com/libsdl-org/SDL/issues/3531
+if (NOT TARGET SDL2::SDL2)
+    find_library(SDL2_LIBRARY
+        NAMES SDL2
+        HINTS "${SDL2_EXEC_PREFIX}"
+        REQUIRED)
+    if (NOT SDL2_LIBRARY)
+        message(FATAL_ERROR "Could not find SDL2 library. Please define SDL2_EXEC_PREFIX and/or SLD2_LIBRARY")
+    endif()
+    add_library(SDL2::SDL2 SHARED IMPORTED)
+    set_target_properties(SDL2::SDL2 PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
+        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+        IMPORTED_LOCATION "${SDL2_LIBRARY}")
+endif()
+
+# Set PROJECT_VERSION of subprojects to "" if it's project call does not set VERSION
+if (POLICY CMP0048)
+    cmake_policy(SET CMP0048 NEW)
+endif()
+
+# Alloc cmake_dependent_option to use "Full Condition Syntax"
+if (POLICY CMP0127)
+    cmake_policy(SET CMP0127 NEW)
+endif()
+
+# OpenGL is required by dependencies of (dependencies of) some vendored libraries
+if (NOT DEFINED OpenGL_GL_PREFERENCE)
+    set(OpenGL_GL_PREFERENCE GLVND)
+endif()
+
+include(CMakeDependentOption)
+include(CMakePackageConfigHelpers)
+include(GNUInstallDirs)
+
+option(VENDORED_DEFAULT "Default value for *_VENDORED options. Can be overridden for each library. Is only used in the first configure run." ON)
+
+option(BACKEND_STB "Add STB backend" OFF)
+cmake_dependent_option(BACKEND_WIC "Add WIC backend (Windows Imaging Component)" OFF "WIN32" OFF)
+cmake_dependent_option(BACKEND_IMAGEIO "Use native Mac OS X frameworks for loading images" ON APPLE OFF)
 
-option(USE_STBIMAGE "Use stb_imge for loading JPEG and PNG images" ON)
 option(SUPPORT_AVIF "Support loading AVIF images" OFF)
+option(SUPPORT_BMP "Support loading BMP images" ON)
+option(SUPPORT_GIF "Support loading GIF images" ON)
 option(SUPPORT_JPG "Support loading JPEG images" ON)
-option(SUPPORT_JXL "Support loading JPEG-XL images" OFF)
+option(SUPPORT_JXL "Support loading JXL images" ON)
+option(SUPPORT_LBM "Support loading LBM images" ON)
+option(SUPPORT_PCX "Support loading PCX images" ON)
 option(SUPPORT_PNG "Support loading PNG images" ON)
-option(SUPPORT_TIFF "Support loading TIFF images" OFF)
+option(SUPPORT_PNM "Support loading PNM images" ON)
+option(SUPPORT_QOI "Support loading QOI images" ON)
+option(SUPPORT_SVG "Support loading SVG images" ON)
+option(SUPPORT_TGA "Support loading TGA images" ON)
+option(SUPPORT_TIF "Support loading TIFF images" ON)
+option(SUPPORT_XCF "Support loading XCF images" ON)
+option(SUPPORT_XPM "Support loading XPM images" ON)
+option(SUPPORT_XV "Support loading XV images" ON)
 option(SUPPORT_WEBP "Support loading WEBP images" OFF)
-option(BUILD_SHOWIMAGE "Build the showimage sample program" OFF)
+
+option(BUILD_SAMPLES "Build the SDL2_image sample program(s)" ON)
 option(BUILD_SHARED_LIBS "Build the library as a shared library" ON)
-if (APPLE)
-	option(ENABLE_APPLE_IMAGEIO "Use native Mac OS X frameworks for loading images" ON)
-endif()
+
+# FIXME: use vendored libavif when available
+set(SUPPORT_AVIF_VENDORED OFF)
+#cmake_dependent_option(SUPPORT_AVIF_VENDORED "Use vendored libavif" ${VENDORED_DEFAULT} SUPPORT_AVIF OFF)
+cmake_dependent_option(SUPPORT_AVIF_SHARED "Dynamically load AVIF support (requires shared libavif)" ON
+    "SUPPORT_AVIF;(SUPPORT_AVIF_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_AVIF_VENDORED" OFF)
+
+cmake_dependent_option(SUPPORT_JPG_VENDORED "Use vendored libjpeg" ${VENDORED_DEFAULT} "SUPPORT_JPG;NOT BACKEND_WIC;NOT BACKEND_STB;NOT BACKEND_IMAGEIO;" OFF)
+cmake_dependent_option(SUPPORT_JPG_SHARED "Dynamically load JPG support (requires shared libjpeg)" ON
+    "SUPPORT_JPG;NOT BACKEND_WIC;NOT BACKEND_STB;NOT BACKEND_IMAGEIO;(SUPPORT_JPG_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_JPG_VENDORED" OFF)
+
+cmake_dependent_option(SUPPORT_JXL_VENDORED "Use vendored libjxl" ${VENDORED_DEFAULT} SUPPORT_JXL OFF)
+cmake_dependent_option(SUPPORT_JXL_SHARED "Dynamically load JXL support (requires shared libjxl)" ON
+    "SUPPORT_JXL;(SUPPORT_JXL_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_JXL_VENDORED" OFF)
+
+cmake_dependent_option(SUPPORT_PNG_VENDORED "Use vendored PNG" ${VENDORED_DEFAULT} "SUPPORT_PNG;NOT BACKEND_WIC;NOT BACKEND_STB;NOT BACKEND_IMAGEIO" OFF)
+cmake_dependent_option(SUPPORT_PNG_SHARED "Dynamically load PNG support (requires shared libpng)" ON
+    "SUPPORT_PNG;NOT BACKEND_WIC;NOT BACKEND_STB;NOT BACKEND_IMAGEIO;(SUPPORT_PNG_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_PNG_VENDORED" OFF)
+cmake_dependent_option(SUPPORT_ZLIB_VENDORED "Use vendored ZLIB (required by PNG)" ${VENDORED_DEFAULT} SUPPORT_PNG_VENDORED OFF)
+
+cmake_dependent_option(SUPPORT_TIF_VENDORED "Use vendored libtiff" ${VENDORED_DEFAULT} SUPPORT_TIF OFF)
+cmake_dependent_option(SUPPORT_TIF_SHARED "Dynamically load TIFF support (requires shared libtiff)" ON
+    "SUPPORT_TIF;(SUPPORT_TIF_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_TIF_VENDORED" OFF)
+
+cmake_dependent_option(SUPPORT_WEBP_VENDORED "Use vendored WEBP" ${VENDORED_DEFAULT} SUPPORT_WEBP OFF)
+cmake_dependent_option(SUPPORT_WEBP_SHARED "Dynamically load WEBP support (requires shared libwebp)" ON
+    "SUPPORT_WEBP;(SUPPORT_WEBP_VENDORED AND BUILD_SHARED_LIBS) OR NOT SUPPORT_WEBP_VENDORED" OFF)
 
 # FIXME: ????
 if (NOT BUILD_SHARED_LIBS)
-	set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 endif()
 
-add_library(SDL2_image)
+add_library(SDL2_image
+    IMG.c
+    IMG_avif.c
+    IMG_bmp.c
+    IMG_gif.c
+    IMG_jpg.c
+    IMG_jxl.c
+    IMG_lbm.c
+    IMG_pcx.c
+    IMG_png.c
+    IMG_pnm.c
+    IMG_qoi.c
+    IMG_stb.c
+    IMG_svg.c
+    IMG_tga.c
+    IMG_tif.c
+    IMG_WIC.c
+    IMG_webp.c
+    IMG_xcf.c
+    IMG_xpm.c
+    IMG_xv.c
+    IMG_xxx.c
+    )
+add_library(SDL2::image ALIAS SDL2_image)
 
-if (UNIX AND NOT APPLE AND NOT ANDROID)
-	# This is compatible with the libtool build
-	set_target_properties(SDL2_image PROPERTIES
-		VERSION ${LT_VERSION}
-		SOVERSION ${LT_MAJOR}
-		OUTPUT_NAME "SDL2_image-${LT_RELEASE}"
-	)
+target_compile_definitions(SDL2_image PRIVATE
+    SDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION}
+    SDL_BUILD_MINOR_VERSION=${MINOR_VERSION}
+    SDL_BUILD_MICRO_VERSION=${MICRO_VERSION}
+    )
+
+if (BACKEND_STB)
+    target_compile_definitions(SDL2_image PRIVATE USE_STBIMAGE)
 endif()
 
-set(IMAGEIO_SOURCES)
 if (APPLE)
-	# TODO: Use DYLIB_COMPATIBILITY_VERSION, DYLIB_CURRENT_VERSION here
-	if (ENABLE_APPLE_IMAGEIO)
-		target_link_options(SDL2_image PRIVATE -Wl,-framework,ApplicationServices)
-		target_link_libraries(SDL2_image PRIVATE objc)
-		set(IMAGEIO_SOURCES "IMG_ImageIO.m")
-	else()
-		target_compile_definitions(SDL2_image PRIVATE SDL_IMAGE_USE_COMMON_BACKEND)
-	endif()
-endif()
-
-target_sources(SDL2_image PRIVATE
-		IMG.c IMG_avif.c IMG_bmp.c IMG_gif.c IMG_jpg.c IMG_jxl.c
-		IMG_lbm.c IMG_pcx.c IMG_png.c IMG_pnm.c IMG_qoi.c IMG_stb.c
-		IMG_svg.c IMG_tga.c IMG_tif.c IMG_webp.c IMG_WIC.c IMG_xcf.c
-		IMG_xpm.c IMG_xv.c IMG_xxx.c
-		${IMAGEIO_SOURCES}
-)
+    if (BACKEND_IMAGEIO)
+        target_link_options(SDL2_image PRIVATE -Wl,-framework,ApplicationServices)
+        target_link_libraries(SDL2_image PRIVATE objc)
+        target_sources(SDL2_image PRIVATE
+            IMG_ImageIO.m
+            )
+    else()
+        target_compile_definitions(SDL2_image PRIVATE SDL_IMAGE_USE_COMMON_BACKEND)
+    endif()
+endif()
 
-target_compile_definitions(SDL2_image PRIVATE
-		-DLOAD_BMP -DLOAD_GIF -DLOAD_LBM -DLOAD_PCX -DLOAD_PNM
-		-DLOAD_QOI -DLOAD_TGA -DLOAD_XCF -DLOAD_XPM -DLOAD_XPM
-		-DLOAD_XV
-)
+if (BACKEND_WIC)
+    target_compile_definitions(SDL2_image PRIVATE SDL_IMAGE_USE_WIC_BACKEND)
+endif()
+
+if (WIN32 AND BUILD_SHARED_LIBS)
+    target_sources(SDL2_image PRIVATE
+        version.rc
+        )
+endif()
+
+set(INSTALL_EXTRA_TARGETS)
+set(PC_REQUIRES)
 
 if (SUPPORT_AVIF)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_AVIF)
-	set(AVIF_CODEC_DAV1D ON)
-	add_subdirectory(external/libavif)
-	include_directories(external/libavif/include)
-	target_link_libraries(SDL2_image PRIVATE avif)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_AVIF)
+    if (SUPPORT_AVIF_VENDORED)
+        message(FATAL_ERROR "libavif is not vendored yet")
+        add_subdirectory(external/libavif EXCLUDE_FROM_ALL)
+        # list(APPEND INSTALL_EXTRA_TARGETS libavif)
+    else()
+        find_package(libavif REQUIRED)
+        list(APPEND PC_REQUIRES libavif)
+    endif()
+    if (SUPPORT_AVIF_SHARED)
+        target_include_Directories(SDL2_image PRIVATE
+            $<TARGET_PROPERTY:avif,INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:avif,INTERFACE_INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:avif,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+        target_get_dynamic_library(dynamic_avif avif)
+        message(STATUS "Dynamic libavif: ${dynamic_avif}")
+        target_compile_definitions(SDL2_image PRIVATE "LOAD_AVIF_DYNAMIC=\"${dynamic_avif}\"")
+        if (SUPPORT_AVIF_VENDORED)
+            add_dependencies(SDL2_image avif)
+        endif()
+    else()
+        target_link_libraries(SDL2_image PRIVATE avif)
+    endif()
 endif()
 
-if (USE_STBIMAGE)
-	target_compile_definitions(SDL2_image PRIVATE -DUSE_STBIMAGE -DLOAD_JPG -DLOAD_PNG)
+if (SUPPORT_BMP)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_BMP)
+endif()
+
+if (SUPPORT_GIF)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_GIF)
 endif()
 
 if (SUPPORT_JPG)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_JPG)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_JPG)
+    if (NOT BACKEND_STB AND NOT BACKEND_WIC AND NOT BACKEND_IMAGEIO)
+        if (SUPPORT_JPG_VENDORED)
+            set(jpeg OFF)
+            add_subdirectory(external/jpeg EXCLUDE_FROM_ALL)
+            add_library(JPEG::JPEG ALIAS jpeg)
+            list(APPEND INSTALL_EXTRA_TARGETS jpeg)
+        else()
+            find_package(JPEG REQUIRED)
+            list(APPEND PC_REQUIRES libjpeg)
+        endif()
+        if (SUPPORT_JPG_SHARED)
+            target_include_Directories(SDL2_image PRIVATE
+                $<TARGET_PROPERTY:JPEG::JPEG,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:JPEG::JPEG,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:JPEG::JPEG,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+                )
+            target_get_dynamic_library(dynamic_jpeg JPEG::JPEG)
+            message(STATUS "Dynamic libjpeg: ${dynamic_jpeg}")
+            target_compile_definitions(SDL2_image PRIVATE "LOAD_JPG_DYNAMIC=\"${dynamic_jpeg}\"")
+            if (SUPPORT_JPG_VENDORED)
+                add_dependencies(SDL2_image JPEG::JPEG)
+            endif()
+        else()
+            target_link_libraries(SDL2_image PRIVATE JPEG::JPEG)
+        endif()
+    endif()
+endif()
+
+if (SUPPORT_JXL)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_JXL)
+    if (SUPPORT_JXL_VENDORED)
+        set(BUILD_TESTING OFF)
+        add_subdirectory(external/libjxl EXCLUDE_FROM_ALL)
+        if (BUILD_SHARED_LIBS)
+            set(jxl_lib jxl)
+            list(APPEND INSTALL_EXTRA_TARGETS brotlidec brotlicommon brotlienc ${jxl_lib})
+        else()
+            set(jxl_lib jxl-static)
+            list(APPEND INSTALL_EXTRA_TARGETS brotlidec-static brotlicommon-static brotlienc-static hwy ${jxl_lib})
+        endif()
+    else()
+        find_library(LIBJXL_LIBRARY NAMES jxl)
+        if (NOT LIBJXL_LIBRARY)
+            message(FATAL_ERROR "Could not find jxl library")
+        endif()
+        find_path(LIBJXL_INCLUDE NAMES jxl/decode.h)
+        if (NOT LIBJXL_INCLUDE)
+            message(FATAL_ERROR "Could not find jxl include directory")
+        endif()
+        add_library(jxl UNKNOWN IMPORTED)
+        set_target_properties(jxl PROPERTIES
+            IMPORTED_LOCATION "${LIBJXL_LIBRARY}"
+            INTERFACE_INCLUDE_DIRECTORIES "${LIBJXL_INCLUDE}"
+            )
+        list(APPEND PC_REQUIRES libjxl)
+        set(jxl_lib jxl)
+    endif()
+    if (SUPPORT_JXL_SHARED)
+        target_include_Directories(SDL2_image PRIVATE
+            $<TARGET_PROPERTY:${jxl_lib},INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:${jxl_lib},INTERFACE_INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:${jxl_lib},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+        target_get_dynamic_library(dynamic_jxl ${jxl_lib})
+        message(STATUS "Dynamic libjxl: ${dynamic_jxl}")
+        target_compile_definitions(SDL2_image PRIVATE "LOAD_JXL_DYNAMIC=\"${dynamic_jxl}\"")
+        if (SUPPORT_JXL_VENDORED)
+            add_dependencies(SDL2_image brotlidec brotlicommon brotlienc ${jxl_lib})
+        endif()
+    else()
+        target_link_libraries(SDL2_image PRIVATE ${jxl_lib})
+    endif()
+endif()
+
+if (SUPPORT_LBM)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_LBM)
+endif()
 
-	if (NOT USE_STBIMAGE)
-		add_subdirectory(external/jpeg)
-		target_link_libraries(SDL2_image PRIVATE jpeg)
-	endif()
+if (SUPPORT_PCX)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_PCX)
 endif()
 
 if (SUPPORT_PNG)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_PNG)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_PNG)
+    if (NOT BACKEND_STB AND NOT BACKEND_WIC AND NOT BACKEND_IMAGEIO)
+        set(HAVE_LD_VERSION_SCRIPT OFF CACHE BOOL "" FORCE)
+        if (SUPPORT_PNG_VENDORED)
+            if (SUPPORT_ZLIB_VENDORED)
+                add_subdirectory(external/zlib EXCLUDE_FROM_ALL)
+                set(PNG_BUILD_ZLIB ON)  # Used by vendored libpng
+                set(ZLIB_INCLUDE_DIR "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/zlib;${CMAKE_CURRENT_BINARY_DIR}/external/zlib>")
+                if (BUILD_SHARED_LIBS)
+                    set(ZLIB_LIBRARY zlib)
+                else()
+                    set(ZLIB_LIBRARY zlibstatic)
+                endif()
+                list(APPEND INSTALL_EXTRA_TARGETS ${ZLIB_LIBRARY})
+            endif()
+            set(SKIP_INSTALL_EXPORT ON)
+            add_subdirectory(external/libpng EXCLUDE_FROM_ALL)
+            if (BUILD_SHARED_LIBS)
+                set(PNG_LIBRARY png)
+            else()
+                set(PNG_LIBRARY png_static)
+            endif()
+            add_library(PNG::PNG ALIAS ${PNG_LIBRARY})
+            target_include_directories(SDL2_image PRIVATE external/libpng)
+            list(APPEND INSTALL_EXTRA_TARGETS ${PNG_LIBRARY})
+        else()
+            find_package(PNG REQUIRED)
+            list(APPEND PC_REQUIRES libpng)
+        endif()
+        if (SUPPORT_PNG_SHARED)
+            target_include_Directories(SDL2_image PRIVATE
+                $<TARGET_PROPERTY:PNG::PNG,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:PNG::PNG,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:PNG::PNG,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+                )
+            target_get_dynamic_library(dynamic_png PNG::PNG)
+            message(STATUS "Dynamic libpng: ${dynamic_png}")
+            target_compile_definitions(SDL2_image PRIVATE "LOAD_PNG_DYNAMIC=\"${dynamic_png}\"")
+            if (SUPPORT_PNG_VENDORED)
+                add_dependencies(SDL2_image PNG::PNG)
+            endif()
+        else()
+            target_link_libraries(SDL2_image PRIVATE PNG::PNG)
+        endif()
+    endif()
+endif()
 
-	if (NOT USE_STBIMAGE)
-		# missing libpng.vers
-		set(HAVE_LD_VERSION_SCRIPT OFF CACHE BOOL "" FORCE)
+if (SUPPORT_PNM)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_PNM)
+endif()
 
-		if (NOT TARGET zlib)
-			# SDL_image doesn't support installing currently
-			set(SKIP_INSTALL_ALL ON CACHE BOOL "" FORCE)
+if (SUPPORT_QOI)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_QOI)
+endif()
 
-			# if zlib not included from another source, add_subdirectory
-			add_subdirectory(external/zlib)
+if (SUPPORT_SVG)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_SVG)
+endif()
 
-			# libpng find_package(zlib) requires ZLIB_INCLUDE_DIR set
-			get_target_property(ZLIB_INCLUDE_DIR zlib INCLUDE_DIRECTORIES)
+if (SUPPORT_TGA)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_TGA)
+endif()
 
-			# libpng find_package(zlib) requires ZLIB_LIBRARY
-			if (BUILD_SHARED_LIBS)
-				set(ZLIB_LIBRARY zlib)
-			else()
-				set(ZLIB_LIBRARY zlibstatic)
-			endif()
-		endif()
+if (SUPPORT_XCF)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_XCF)
+endif()
 
-		add_subdirectory(external/libpng)
-		include_directories(external/libpng)
-		if (BUILD_SHARED_LIBS)
-			target_link_libraries(SDL2_image PRIVATE png)
-		else()
-			target_link_libraries(SDL2_image PRIVATE png_static)
-		endif()
-	endif()
+if (SUPPORT_XPM)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_XPM)
 endif()
 
-if (SUPPORT_JXL)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_JXL)
-	set(JPEGXL_ENABLE_FUZZERS false)
-	set(JPEGXL_ENABLE_TOOLS false)
-	set(JPEGXL_ENABLE_MANPAGES false)
-	set(JPEGXL_ENABLE_BENCHMARK false)
-	set(JPEGXL_ENABLE_EXAMPLES false)
-	set(JPEGXL_ENABLE_SJPEG false)
-	set(JPEGXL_ENABLE_OPENEXR false)
-	set(JPEGXL_ENABLE_SKCMS false)
-	add_subdirectory(external/libjxl)
-	include_directories(external/libjxl/lib/include)
-	include_directories(${CMAKE_BINARY_DIR}/external/libjxl/lib/include)
-	target_link_libraries(SDL2_image PRIVATE jxl)
-endif()
-
-if (SUPPORT_TIFF)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_TIF)
-	add_subdirectory(external/libtiff)
-	target_link_libraries(SDL2_image PRIVATE tiff)
+if (SUPPORT_XV)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_XV)
 endif()
 
-if (SUPPORT_WEBP)
-	target_compile_definitions(SDL2_image PRIVATE -DLOAD_WEBP)
-	# missing cpufeatures
-	add_subdirectory(external/libwebp)
-	include_directories(external/libwebp/src)
-	target_link_libraries(SDL2_image PRIVATE webp)
+if (SUPPORT_TIF)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_TIF)
+    # FIXME: libtiff might need zlib
+    if (SUPPORT_TIF_VENDORED)
+        add_subdirectory(external/libtiff EXCLUDE_FROM_ALL)
+        add_library(TIFF::TIFF ALIAS tiff)
+        list(APPEND INSTALL_EXTRA_TARGETS tiff)
+    else()
+        find_package(TIFF REQUIRED)
+        list(APPEND PC_REQUIRES libtiff-4)
+    endif()
+    if (SUPPORT_TIF_SHARED)
+        target_include_Directories(SDL2_image PRIVATE
+            $<TARGET_PROPERTY:TIFF::TIFF,INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:TIFF::TIFF,INTERFACE_INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:TIFF::TIFF,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+        target_get_dynamic_library(dynamic_tif TIFF::TIFF)
+        message(STATUS "Dynamic libtiff: ${dynamic_tif}")
+        target_compile_definitions(SDL2_image PRIVATE "LOAD_TIF_DYNAMIC=\"${dynamic_tif}\"")
+        if (SUPPORT_TIF_VENDORED)
+            add_dependencies(SDL2_image TIFF::TIFF)
+        endif()
+    else()
+        target_link_libraries(SDL2_image PRIVATE TIFF::TIFF)
+    endif()
 endif()
 
-add_library(SDL2::image ALIAS SDL2_image)
+if (SUPPORT_WEBP)
+    target_compile_definitions(SDL2_image PRIVATE LOAD_WEBP)
+    # missing cpufeatures
+    if (SUPPORT_WEBP_VENDORED)
+        add_subdirectory(external/libwebp EXCLUDE_FROM_ALL)
+        target_include_directories(SDL2_image PRIVATE external/libwebp/src)
+        add_library(WebP::webp ALIAS webp)
+        list(APPEND INSTALL_EXTRA_TARGETS webp)
+    else()
+        find_library(WEBP_LIBRARY NAMES webp)
+        if (NOT WEBP_LIBRARY)
+            message(FATAL_ERROR "Could not find webp library")
+        endif()
+        find_path(WEBP_INCLUDE NAMES webp/decode.h)
+        if (NOT WEBP_INCLUDE)
+            message(FATAL_ERROR "Could not find webp include directory")
+        endif()
+        add_library(webp UNKNOWN IMPORTED)
+        set_target_properties(webp PROPERTIES
+            IMPORTED_LOCATION "${WEBP_LIBRARY}"
+            INTERFACE_INCLUDE_DIRECTORIES "${WEBP_INCLUDE}"
+            )
+        list(APPEND PC_REQUIRES libwebp)
+        add_library(WebP::webp ALIAS webp)
+    endif()
+    if (SUPPORT_WEBP_SHARED)
+        target_include_Directories(SDL2_image PRIVATE
+            $<TARGET_PROPERTY:WebP::webp,INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:WebP::webp,INTERFACE_INCLUDE_DIRECTORIES>
+            $<TARGET_PROPERTY:WebP::webp,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+        target_get_dynamic_library(dynamic_webp WebP::webp)
+        message(STATUS "Dynamic libwebp: ${dynamic_webp}")
+        target_compile_definitions(SDL2_image PRIVATE "LOAD_WEBP_DYNAMIC=\"${dynamic_webp}\"")
+        if (SUPPORT_WEBP_VENDORED)
+            add_dependencies(SDL2_image WebP::webp)
+        endif()
+    else()
+        target_link_libraries(SDL2_image PRIVATE WebP::webp)
+    endif()
+endif()
 
-target_include_directories(SDL2_image PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(SDL2_image
+    PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+    PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>
+    )
+
+set_target_properties(SDL2_image PROPERTIES
+    DEFINE_SYMBOL DLL_EXPORT
+    PUBLIC_HEADER SDL_image.h
+    EXPORT_NAME SDL2_image
+    C_VISIBILITY_PRESET "hidden"
+    )
+if (UNIX AND NOT APPLE AND NOT ANDROID)
+    set_target_properties(SDL2_image PROPERTIES
+        SOVERSION "${LT_MAJOR}"
+        VERSION "${LT_VERSION}"
+        )
+endif()
+if (BUILD_SHARED_LIBS)
+    if (WIN32)
+        set_target_properties(SDL2_image PROPERTIES
+            PREFIX ""
+            )
+    elseif (UNIX AND NOT APPLE AND NOT ANDROID)
+        set_target_properties(SDL2_image PROPERTIES
+            OUTPUT_NAME "SDL2_image-${LT_RELEASE}"
+            )
+    endif()
+endif()
 
 if (BUILD_SHARED_LIBS)
-	if(WIN32)
-	  target_compile_definitions(SDL2_image PRIVATE -DDLL_EXPORT)
-	  target_sources(SDL2_image PRIVATE version.rc)
-	endif()
-	target_link_libraries(SDL2_image PUBLIC SDL2::SDL2)
+    target_link_libraries(SDL2_image PRIVATE SDL2::SDL2)
 else()
-	target_link_libraries(SDL2_image PUBLIC SDL2::SDL2-static)
+    target_link_libraries(SDL2_image PRIVATE SDL2::SDL2-static)
+endif()
+
+install(TARGETS SDL2_image EXPORT SDL2ImageExports
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL2"
+    )
+
+if (INSTALL_EXTRA_TARGETS)
+    install(TARGETS ${INSTALL_EXTRA_TARGETS} EXPORT SDL2ImageExports
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        PUBLIC_HEADER DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/external_include"
+        )
+endif()
+
+configure_package_config_file(SDL2_image-config.cmake.in SDL2_image-config.cmake
+    INSTALL_DESTINATION "${CMAKE_INSTALL_LBDIR}/cmake/SDL2_image")
+
+set(prefix "${CMAKE_INSTALL_PREFIX}")
+set(exec_prefix "${CMAKE_INSTALL_FULL_LIBEXECDIR}")
+set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
+set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
+set(PACKAGE "${PROJECT_NAME}")
+set(VERSION "${FULL_VERSION}")
+set(SDL_VERSION "${SDL_REQUIRED_VERSION}")
+string(JOIN " " PC_REQUIRES ${PC_REQUIRES})
+configure_file(SDL2_image.pc.in SDL2_image.pc @ONLY)
+
+install(EXPORT SDL2ImageExports NAMESPACE SDL2::
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2_image" FILE SDL2_image-targets.cmake)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SDL2_image-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2_image")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SDL2_image.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+install(FILES "LICENSE.txt" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}")
+if (NOT (WIN32 OR CYGWIN OR MINGW))
+    if(BUILD_SHARED_LIBS)
+        set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
+        get_target_property(SONAME SDL2_image OUTPUT_NAME)
+        if(NOT ANDROID)
+            install(CODE "
+				execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
+					\"lib${SONAME}${SOEXT}\" \"libSDL2_image${SOEXT}\"
+					WORKING_DIRECTORY \"${PROJECT_BINARY_DIR}\")")
+            install(FILES ${PROJECT_BINARY_DIR}/libSDL2_image${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+        endif()
+    endif()
 endif()
 
-if(BUILD_SHOWIMAGE)
-	add_executable(showimage showimage.c)
-	target_link_libraries(showimage PRIVATE SDL2::image)
-	if (WIN32)
-		target_link_libraries(showimage PRIVATE SDL2::SDL2main)
-	endif()
+if (BUILD_SAMPLES)
+    add_executable(showanim showanim.c)
+    add_executable(showimage showimage.c)
+
+    foreach(prog showanim showimage)
+        if (MINGW)
+            target_link_libraries(${prog} PRIVATE mingw32)
+            target_link_options(${prog} PRIVATE -mwindows)
+        endif()
+        target_link_libraries(${prog} PRIVATE SDL2::image)
+        if (TARGET SDL2::SDL2main)
+            target_link_libraries(${prog} PRIVATE SDL2::SDL2main)
+        endif()
+        if (BUILD_SHARED_LIBS)
+            target_link_libraries(${prog} PRIVATE SDL2::SDL2)
+        else()
+            target_link_libraries(${prog} PRIVATE SDL2::SDL2-static)
+        endif()
+    endforeach()
 endif()
diff --git a/SDL2_image-config.cmake.in b/SDL2_image-config.cmake.in
new file mode 100644
index 0000000..5f13510
--- /dev/null
+++ b/SDL2_image-config.cmake.in
@@ -0,0 +1,56 @@
+set(SDL2_IMAGE_SUPPORT_BMP   @SUPPORT_BMP@)
+set(SDL2_IMAGE_SUPPORT_GIF   @SUPPORT_GIF@)
+set(SDL2_IMAGE_SUPPORT_JPG   @SUPPORT_JPG@)
+set(SDL2_IMAGE_SUPPORT_JXL   @SUPPORT_JXL@)
+set(SDL2_IMAGE_SUPPORT_LBM   @SUPPORT_LBM@)
+set(SDL2_IMAGE_SUPPORT_PCX   @SUPPORT_PCX@)
+set(SDL2_IMAGE_SUPPORT_PNG   @SUPPORT_PNG@)
+set(SDL2_IMAGE_SUPPORT_PNM   @SUPPORT_PNM@)
+set(SDL2_IMAGE_SUPPORT_QOI   @SUPPORT_QOI@)
+set(SDL2_IMAGE_SUPPORT_STB   @SUPPORT_STB@)
+set(SDL2_IMAGE_SUPPORT_SVG   @SUPPORT_SVG@)
+set(SDL2_IMAGE_SUPPORT_TGA   @SUPPORT_TGA@)
+set(SDL2_IMAGE_SUPPORT_TIF   @SUPPORT_TIF@)
+set(SDL2_IMAGE_SUPPORT_XCF   @SUPPORT_XCF@)
+set(SDL2_IMAGE_SUPPORT_XPM   @SUPPORT_XPM@)
+set(SDL2_IMAGE_SUPPORT_XV    @SUPPORT_XV@)
+set(SDL2_IMAGE_SUPPORT_WEBP  @SUPPORT_WEBP@)
+
+include(CMakeFindDependencyMacro)
+
+if (NOT ANDROID AND NOT (TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static))
+	find_dependency(SDL2 REQUIRED)
+endif()
+
+if(SDL2_IMAGE_SUPPORT_JPG AND NOT @SUPPORT_JPG_VENDORED@)
+	find_dependency(JPEG REQUIRED)
+endif()
+
+if(SDL2_IMAGE_SUPPORT_JXL AND NOT @SUPPORT_JXL_VENDORED@)
+	find_library(LIBJXL_LIBRARY NAMES jxl)
+	if (NOT LIBJXL_LIBRARY)
+		message(FATAL_ERROR "Could not find jxl library")
+	endif()
+	find_path(LIBJXL_INCLUDE NAMES jxl/decode.h)
+	if (NOT LIBJXL_INCLUDE)
+		message(FATAL_ERROR "Could not find jxl include directory")
+	endif()
+	add_library(jxl UNKNOWN IMPORTED)
+endif()
+
+if(SDL2_IMAGE_SUPPORT_PNG AND NOT @SUPPORT_PNG_VENDORED@)
+	if(NOT @SUPPORT_ZLIB_VENDORED@)
+		find_package(ZLIB REQUIRED)
+	endif()
+	find_package(PNG REQUIRED)
+endif()
+
+if(SDL2_IMAGE_SUPPORT_TIF AND NOT @SUPPORT_TIF_VENDORED@)
+	find_package(TIFF REQUIRED)
+endif()
+
+if(SDL2_IMAGE_SUPPORT_WEBP AND NOT @SUPPORT_WEBP_VENDORED@)
+	find_package(WebP REQUIRED)
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/SDL2_image-targets.cmake")
diff --git a/test-versioning.sh b/test-versioning.sh
index 733029d..210b724 100755
--- a/test-versioning.s

(Patch may be truncated, please check the link at the top of this post.)