From 4ba0cf79115f351d51c7eac5a34b6bd9c1420d1b Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Thu, 12 May 2022 04:06:06 +0200
Subject: [PATCH] Improve CMake build system
- Use 'SDL2IMAGE_' prefix for all options
- Create SDL2_image::SDL2_image when building a shared library,
create SDL2_image::SDL2_image-static when building a static library
- Use same CMake layout as SDL_ttf/SDL_mixer
- Create libSDL2_imaged.so symbolic link (when building debug build type)
- Add PrivateSdlFunctions.cmake script for common functionality between SDL_XXX
- Add FindXXX.cmake scripts for dependencies that don't provide one
- Add CMakeLists.txt + cmake scripts to source distribution
- Bring jpeg/png saving support to cmake
- Update the git submodules
- Test CMake on mingw64 (using system dependencies there)
- Add MacOS CI
- Create symbolic link at build time + install it
- Add Macos versioning
- Add single SDL2IMAGE_VENDORED option to enable vendoring of
dependencies
---
.github/workflows/main.yml | 51 +-
CMakeLists.txt | 955 ++++++++++++++++----------------
SDL2_imageConfig.cmake.in | 121 ++--
cmake/Findlibjxl.cmake | 32 ++
cmake/Findwebp.cmake | 32 ++
cmake/PrivateSdlFunctions.cmake | 232 ++++++++
external/jpeg | 2 +-
external/libjxl | 2 +-
release_checklist.md | 3 +
test-versioning.sh | 9 +
test/CMakeLists.txt | 21 +-
11 files changed, 878 insertions(+), 582 deletions(-)
create mode 100644 cmake/Findlibjxl.cmake
create mode 100644 cmake/Findwebp.cmake
create mode 100644 cmake/PrivateSdlFunctions.cmake
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c8039738..017c0547 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -15,10 +15,13 @@ jobs:
fail-fast: false
matrix:
platform:
- - { name: Windows (mingw32), os: windows-latest, shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686 }
- - { name: Windows (mingw64), os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64 }
- - { name: Linux (CMake), os: ubuntu-20.04, shell: sh, cmake: '-GNinja' }
- - { name: Linux (autotools), os: ubuntu-20.04, shell: sh }
+ - { name: Windows (mingw32+autotools), os: windows-latest, shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686 }
+ - { name: Windows (mingw64+CMake), os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64,
+ cmake: '-DSDL2IMAGE_BACKEND_STB=OFF -DSDL2IMAGE_BACKEND_WIC=OFF -DSDL2IMAGE_VENDORED=OFF -DSDL2IMAGE_AVIF=ON -G "Ninja Multi-Config"' }
+ - { name: Linux (autotools), os: ubuntu-20.04, shell: sh }
+ - { name: Linux (CMake), os: ubuntu-20.04, shell: sh, cmake: '-DSDL2IMAGE_VENDORED=ON -GNinja' }
+ - { name: Macos (autotools), os: macos-latest, shell: sh }
+ - { name: Macos (CMake), os: macos-latest, shell: sh, cmake: '-DSDL2IMAGE_VENDORED=ON -GNinja' }
steps:
- name: Set up MSYS2
@@ -31,14 +34,32 @@ jobs:
${{ matrix.platform.msys-env }}-autotools
${{ matrix.platform.msys-env }}-cmake
${{ matrix.platform.msys-env }}-gcc
+ ${{ matrix.platform.msys-env }}-libavif
${{ matrix.platform.msys-env }}-libjpeg-turbo
+ ${{ matrix.platform.msys-env }}-libjxl
${{ matrix.platform.msys-env }}-libpng
${{ matrix.platform.msys-env }}-libtiff
${{ matrix.platform.msys-env }}-libwebp
${{ matrix.platform.msys-env }}-ninja
${{ matrix.platform.msys-env }}-pkg-config
${{ matrix.platform.msys-env }}-zlib
-
+ - name: Setup Macos dependencies
+ if: runner.os == 'macOS'
+ run: |
+ brew install \
+ autoconf \
+ automake \
+ jpeg \
+ libavif \
+ libpng \
+ libtiff \
+ libtool \
+ ninja \
+ pkg-config \
+ sdl2 \
+ webp \
+ zlib \
+ ${NULL+}
- name: Setup Linux dependencies
if: runner.os == 'Linux'
run: |
@@ -47,7 +68,6 @@ jobs:
autoconf \
automake \
cmake \
- gnome-desktop-testing \
libjpeg-dev \
libpng-dev \
libsdl2-dev \
@@ -58,6 +78,7 @@ jobs:
pkg-config \
zlib1g-dev \
${NULL+}
+
- uses: actions/checkout@v2
with:
submodules: recursive
@@ -70,23 +91,23 @@ jobs:
if: "matrix.platform.cmake"
run: |
cmake -B build \
- -DBUILD_SAMPLES=ON \
- -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
- -DCMAKE_VERBOSE_MAKEFILE=ON \
- -DSUPPORT_JXL=OFF \
- -DSUPPORT_TIF=ON \
- -DSUPPORT_WEBP=ON \
+ -DBUILD_SHARED_LIBS=ON \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DSDL2IMAGE_SAMPLES=ON \
+ -DSDL2IMAGE_JXL=ON \
+ -DSDL2IMAGE_TIF=ON \
+ -DSDL2IMAGE_WEBP=ON \
${{ matrix.platform.cmake }}
- name: Build
if: "matrix.platform.cmake"
- run: cmake --build build/ --config Release
+ run: cmake --build build/ --config Release --verbose
- name: Install
if: "matrix.platform.shell == 'sh' && matrix.platform.cmake"
run: |
set -eu
rm -fr DESTDIR-cmake
DESTDIR=$(pwd)/DESTDIR-cmake cmake --install build/ --config Release
- ( cd DESTDIR-cmake; find ) | LC_ALL=C sort -u
+ find DESTDIR-cmake | LC_ALL=C sort -u
- name: Configure Autotools
if: "! matrix.platform.cmake"
@@ -147,7 +168,7 @@ jobs:
rm -fr DESTDIR-autotools
mkdir DESTDIR-autotools
make -j"${parallel}" -C build-autotools install DESTDIR="${curdir}/DESTDIR-autotools" V=1
- ( cd DESTDIR-autotools; find ) | LC_ALL=C sort -u
+ find DESTDIR-autotools | LC_ALL=C sort -u
- name: Distcheck with Autotools
if: "runner.os == 'Linux' && ! matrix.platform.cmake"
run: |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24978ecc..da06d955 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,315 +1,175 @@
cmake_minimum_required(VERSION 3.14)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
+
# 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}")
set(SDL_REQUIRED_VERSION 2.0.8)
+# For historical reasons this is 3.0.0 rather than the expected 1.0.0
+set(DYLIB_COMPATIBILITY_VERSION "3.0.0")
+
+include(PrivateSdlFunctions)
+sdl_calculate_derived_version_variables()
+
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+ message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL_image source code and call cmake from there")
+endif()
+
+project(SDL2_image
+ LANGUAGES C
+ VERSION "${FULL_VERSION}"
+)
+
+message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}")
+
# Set defaults preventing destination file conflicts
-set(SDL_CMAKE_DEBUG_POSTFIX "d"
+set(SDL2IMAGE_DEBUG_POSTFIX "d"
CACHE STRING "Name suffix for debug builds")
+mark_as_advanced(SDL2IMAGE_DEBUG_POSTFIX)
-mark_as_advanced(CMAKE_IMPORT_LIBRARY_SUFFIX SDL_CMAKE_DEBUG_POSTFIX)
-
-# Calculate a libtool-like version number
-math(EXPR BINARY_AGE "${MINOR_VERSION} * 100 + ${MICRO_VERSION}")
-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)
+# Assume MSVC projects don't have a package manager and need vendored dependencies (by default).
+# Most other platforms have some kind of package manager.
+# FIXME: consider a package manager such as conan/vcpkg instead of vendoring
+if(MSVC)
+ set(vendored_default ON)
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,
-# we should rename the library from SDL2 to SDL3, at which point this would
-# reset to 0 anyway.
-set(LT_MAJOR "0")
-
-math(EXPR LT_AGE "${BINARY_AGE} - ${INTERFACE_AGE}")
-math(EXPR LT_CURRENT "${LT_MAJOR} + ${LT_AGE}")
-set(LT_REVISION "${INTERFACE_AGE}")
-# For historical reasons, the library name redundantly includes the major
-# version twice: libSDL2_image-2.0.so.0.
-# TODO: in SDL 3, set the OUTPUT_NAME to plain SDL3_image, which will simplify
-# it to libSDL3_image.so.0
-set(LT_RELEASE "2.0")
-set(LT_VERSION "${LT_MAJOR}.${LT_AGE}.${LT_REVISION}")
-
-# The following should match the versions in the Xcode project file.
-# Each version is 1 higher than you might expect, for compatibility
-# with libtool: macOS ABI versioning is 1-based, unlike other platforms
-# which are normally 0-based.
-math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${LT_MAJOR} + ${LT_AGE} + 1")
-math(EXPR DYLIB_CURRENT_VERSION_MINOR "${LT_REVISION}")
-math(EXPR DYLIB_COMPAT_VERSION_MAJOR "${LT_MAJOR} + 1")
-set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.0")
-# For historical reasons this is 3.0.0 rather than the expected 1.0.0
-set(DYLIB_COMPATIBILITY_VERSION "3.0.0")
+ set(vendored_default OFF)
+endif()
-project(SDL2_image LANGUAGES C
- VERSION "${FULL_VERSION}")
+include(CMakeDependentOption)
+include(CMakePackageConfigHelpers)
+include(GNUInstallDirs)
-message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}")
+option(CMAKE_POSITION_INDEPENDENT_CODE "Build static libraries with -fPIC" ON)
+option(BUILD_SHARED_LIBS "Build the library as a shared library" ON)
-if (NOT (TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static))
- find_package(SDL2 REQUIRED)
+option(SDL2IMAGE_INSTALL "Enable SDL2_image install target" ON)
+option(SDL2IMAGE_VENDORED "Use vendored third-party libraries" ${vendored_default})
+
+option(SDL2IMAGE_SAMPLES "Build the SDL2_image sample program(s)" ON)
+cmake_dependent_option(SDL2IMAGE_SAMPLES_INSTALL "Install the SDL2_image sample program(s)" OFF "SDL2IMAGE_SAMPLES;SDL2IMAGE_INSTALL" OFF)
+
+option(SDL2IMAGE_TESTS "Build unit tests?" OFF)
+cmake_dependent_option(SDL2IMAGE_TESTS_INSTALL "Install unit tests?" OFF "SDL2IMAGE_TESTS;SDL2IMAGE_INSTALL" OFF)
+
+option(SDL2IMAGE_BACKEND_STB "Use stb_image for loading JPEG and PNG files" ON)
+cmake_dependent_option(SDL2IMAGE_BACKEND_WIC "Add WIC backend (Windows Imaging Component)" OFF WIN32 OFF)
+cmake_dependent_option(SDL2IMAGE_BACKEND_IMAGEIO "Use native Mac OS X frameworks for loading images" ON APPLE OFF)
+
+option(SDL2IMAGE_AVIF "Support loading AVIF images" OFF)
+option(SDL2IMAGE_BMP "Support loading BMP images" ON)
+option(SDL2IMAGE_GIF "Support loading GIF images" ON)
+option(SDL2IMAGE_JPG "Support loading JPEG images" ON)
+option(SDL2IMAGE_JXL "Support loading JXL images" OFF)
+option(SDL2IMAGE_LBM "Support loading LBM images" ON)
+option(SDL2IMAGE_PCX "Support loading PCX images" ON)
+option(SDL2IMAGE_PNG "Support loading PNG images" ON)
+option(SDL2IMAGE_PNM "Support loading PNM images" ON)
+option(SDL2IMAGE_QOI "Support loading QOI images" ON)
+option(SDL2IMAGE_SVG "Support loading SVG images" ON)
+option(SDL2IMAGE_TGA "Support loading TGA images" ON)
+option(SDL2IMAGE_TIF "Support loading TIFF images" OFF)
+option(SDL2IMAGE_WEBP "Support loading WEBP images" OFF)
+option(SDL2IMAGE_XCF "Support loading XCF images" ON)
+option(SDL2IMAGE_XPM "Support loading XPM images" ON)
+option(SDL2IMAGE_XV "Support loading XV images" ON)
+
+cmake_dependent_option(SDL2IMAGE_JPG_SAVE "Add JPEG save support" ON SDL2IMAGE_JPG OFF)
+cmake_dependent_option(SDL2IMAGE_PNG_SAVE "Add PNG save support" ON SDL2IMAGE_PNG OFF)
+
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_AVIF)
+ set(SDL2IMAGE_AVIF_VENDORED ON)
+else()
+ set(SDL2IMAGE_AVIF_VENDORED OFF)
endif()
+cmake_dependent_option(SDL2IMAGE_AVIF_SHARED "Dynamically load AVIF support (requires shared libavif)"
+ ON SDL2IMAGE_AVIF OFF)
-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(win32_implib_identify_dll DEST IMPLIB)
- cmake_parse_arguments(ARGS "NOTFATAL" "" "" ${ARGN})
- if (CMAKE_DLLTOOL)
- execute_process(
- COMMAND "${CMAKE_DLLTOOL}" --identify "${IMPLIB}"
- RESULT_VARIABLE retcode
- OUTPUT_VARIABLE stdout
- ERROR_VARIABLE stderr)
- if (NOT retcode EQUAL 0)
- if (NOT ARGS_NOTFATAL)
- message(FATAL_ERROR "${CMAKE_DLLTOOL} failed.")
- else()
- set("${DEST}" "${DEST}-NOTFOUND" PARENT_SCOPE)
- return()
- endif()
- endif()
- string(STRIP "${stdout}" result)
- set(${DEST} "${result}" PARENT_SCOPE)
- elseif (MSVC)
- get_filename_component(CMAKE_C_COMPILER_DIRECTORY "${CMAKE_C_COMPILER}" DIRECTORY CACHE)
- find_program(CMAKE_DUMPBIN NAMES dumpbin PATHS "${CMAKE_C_COMPILER_DIRECTORY}")
- if (CMAKE_DUMPBIN)
- execute_process(
- COMMAND "${CMAKE_DUMPBIN}" "-headers" "${IMPLIB}"
- RESULT_VARIABLE retcode
- OUTPUT_VARIABLE stdout
- ERROR_VARIABLE stderr)
- if (NOT retcode EQUAL 0)
- if (NOT ARGS_NOTFATAL)
- message(FATAL_ERROR "dumpbin failed.")
- else()
- set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE)
- return()
- endif()
- endif()
- string(REGEX MATCH "DLL name[ ]+:[ ]+([^\n]+)\n" match "${stdout}")
- if (NOT match)
- if (NOT ARGS_NOTFATAL)
- message(FATAL_ERROR "dumpbin did not find any associated dll for ${IMPLIB}.")
- else()
- set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE)
- return()
- endif()
- endif()
- set(result "${CMAKE_MATCH_1}")
- set(${DEST} "${result}" PARENT_SCOPE)
- else()
- message(FATAL_ERROR "Cannot find dumpbin, please set CMAKE_DUMPBIN cmake variable")
- endif()
- else()
- if (NOT ARGS_NOTFATAL)
- message(FATAL_ERROR "Don't know how to identify dll from import library. Set CMAKE_DLLTOOL (for mingw) or CMAKE_DUMPBIN (for MSVC)")
- else()
- set(${DEST} "${DEST}-NOTFOUND")
- endif()
- endif()
-endfunction()
-
-function(target_get_dynamic_library DEST TARGET)
- set(result)
- get_target_property(alias "${TARGET}" ALIASED_TARGET)
- while (alias)
- set(TARGET "${alias}")
- get_target_property(alias "${TARGET}" ALIASED_TARGET)
- endwhile()
- if (WIN32)
- # Use the target dll of the import library
- set(props_to_check IMPORTED_IMPLIB)
- if (CMAKE_BUILD_TYPE)
- list(APPEND props_to_check IMPORTED_IMPLIB_${CMAKE_BUILD_TYPE})
- endif()
- list(APPEND props_to_check IMPORTED_LOCATION)
- if (CMAKE_BUILD_TYPE)
- list(APPEND props_to_check IMPORTED_LOCATION_${CMAKE_BUILD_TYPE})
- endif()
- foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL)
- list(APPEND props_to_check IMPORTED_IMPLIB_${config_type})
- list(APPEND props_to_check IMPORTED_LOCATION_${config_type})
- endforeach()
-
- foreach(prop_to_check ${props_to_check})
- if (NOT result)
- get_target_property(propvalue "${TARGET}" ${prop_to_check})
- if (propvalue AND EXISTS "${propvalue}")
- win32_implib_identify_dll(result "${propvalue}" NOTFATAL)
- endif()
- endif()
- endforeach()
- else()
- # 1. find the target library a file might be symbolic linking to
- # 2. find all other files in the same folder that symolic link to it
- # 3. sort all these files, and select the 2nd item
- set(props_to_check IMPORTED_LOCATION)
- if (CMAKE_BUILD_TYPE)
- list(APPEND props_to_check IMPORTED_LOCATION_${CMAKE_BUILD_TYPE})
- endif()
- foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL)
- list(APPEND props_to_check IMPORTED_LOCATION_${config_type})
- endforeach()
- foreach(prop_to_check ${props_to_check})
- if (NOT result)
- get_target_property(propvalue "${TARGET}" ${prop_to_check})
- if (EXISTS "${propvalue}")
- while (IS_SYMLINK "${propvalue}")
- read_absolute_symlink(propvalue "${propvalue}")
- endwhile()
- get_filename_component(libdir "${propvalue}" DIRECTORY)
- file(GLOB subfiles "${libdir}/*")
- set(similar_files "${propvalue}")
- foreach(subfile ${subfiles})
- if (IS_SYMLINK "${subfile}")
- read_absolute_symlink(subfile_target "${subfile}")
- if (subfile_target STREQUAL propvalue)
- list(APPEND similar_files "${subfile}")
- endif()
- endif()
- endforeach()
- list(SORT similar_files)
- list(LENGTH similar_files eq_length)
- if (eq_length GREATER 1)
- list(GET similar_files 1 item)
- else()
- list(GET similar_files 0 item)
- endif()
- get_filename_component(result "${item}" NAME)
- endif()
- endif()
- endforeach()
- endif()
- if (NOT result)
- set (result "$<TARGET_FILE_NAME:${TARGET}>")
- 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 OR TARGET SDL2::SDL2-static))
- 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}")
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_JPG AND NOT (SDL2IMAGE_BACKEND_WIC OR SDL2IMAGE_BACKEND_STB OR SDL2IMAGE_BACKEND_IMAGEIO))
+ set(SDL2IMAGE_JPG_VENDORED ON)
+else()
+ set(SDL2IMAGE_JPG_VENDORED OFF)
endif()
+cmake_dependent_option(SDL2IMAGE_JPG_SHARED "Dynamically load JPG support (requires shared libjpeg)"
+ ON "SDL2IMAGE_JPG;NOT SDL2IMAGE_BACKEND_WIC;NOT SDL2IMAGE_BACKEND_STB;NOT SDL2IMAGE_BACKEND_IMAGEIO" OFF)
-# Set PROJECT_VERSION of subprojects to "" if it's project call does not set VERSION
-if (POLICY CMP0048)
- cmake_policy(SET CMP0048 NEW)
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_JXL)
+ set(SDL2IMAGE_JXL_VENDORED ON)
+else()
+ set(SDL2IMAGE_JXL_VENDORED OFF)
endif()
+cmake_dependent_option(SDL2IMAGE_JXL_SHARED "Dynamically load JXL support (requires shared libjxl)"
+ ON SDL2IMAGE_JXL OFF)
-# Alloc cmake_dependent_option to use "Full Condition Syntax"
-if (POLICY CMP0127)
- cmake_policy(SET CMP0127 NEW)
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_PNG AND NOT (SDL2IMAGE_BACKEND_WIC OR SDL2IMAGE_BACKEND_STB OR SDL2IMAGE_BACKEND_IMAGEIO))
+ set(SDL2IMAGE_PNG_VENDORED ON)
+else()
+ set(SDL2IMAGE_PNG_VENDORED OFF)
endif()
+cmake_dependent_option(SDL2IMAGE_PNG_SHARED "Dynamically load PNG support (requires shared libpng)"
+ ON "SDL2IMAGE_PNG;NOT SDL2IMAGE_BACKEND_WIC;NOT SDL2IMAGE_BACKEND_STB;NOT SDL2IMAGE_BACKEND_IMAGEIO" OFF)
-# OpenGL is required by dependencies of (dependencies of) some vendored libraries
-if (NOT DEFINED OpenGL_GL_PREFERENCE)
- set(OpenGL_GL_PREFERENCE GLVND)
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_TIF)
+ set(SDL2IMAGE_TIF_VENDORED ON)
+else()
+ set(SDL2IMAGE_TIF_VENDORED OFF)
endif()
+cmake_dependent_option(SDL2IMAGE_TIF_SHARED "Dynamically load TIFF support (requires shared libtiff)"
+ ON SDL2IMAGE_TIF OFF)
-include(CMakeDependentOption)
-include(CMakePackageConfigHelpers)
-include(GNUInstallDirs)
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_WEBP)
+ set(SDL2IMAGE_WEBP_VENDORED ON)
+else()
+ set(SDL2IMAGE_WEBP_VENDORED OFF)
+endif()
+cmake_dependent_option(SDL2IMAGE_WEBP_SHARED "Dynamically load WEBP support (requires shared libwebp)"
+ ON SDL2IMAGE_WEBP OFF)
-option(BUILD_TESTS "Build unit tests?" OFF)
-cmake_dependent_option(INSTALL_TESTS "Install unit tests?" OFF BUILD_TESTS OFF)
-option(VENDORED_DEFAULT "Default value for *_VENDORED options. Can be overridden for each library. Is only used in the first configure run." ON)
-option(SDL2_IMAGE_DISABLE_INSTALL "Disable installing SDL2_image" OFF)
-
-option(BACKEND_STB "Use stb_image for loading JPEG and PNG files" ON)
-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(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 JXL images" OFF)
-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_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" OFF)
-option(SUPPORT_WEBP "Support loading WEBP images" OFF)
-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(BUILD_SAMPLES "Build the SDL2_image sample program(s)" ON)
-option(BUILD_SHARED_LIBS "Build the library as a shared library" ON)
-# 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)
+if(SDL2IMAGE_VENDORED AND SDL2IMAGE_PNG_VENDORED)
+ set(SDL2IMAGE_ZLIB_VENDORED ON)
+else()
+ set(SDL2IMAGE_ZLIB_VENDORED OFF)
+endif()
+if(SDL2IMAGE_PNG_SHARED)
+ set(SDL2IMAGE_ZLIB_SHARED ON)
+else()
+ set(SDL2IMAGE_ZLIB_SHARED OFF)
endif()
-if(BUILD_SHARED_LIBS)
+# Save BUILD_SHARED_LIBS variable
+set(SDL2IMAGE_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
+
+if(SDL2IMAGE_BUILD_SHARED_LIBS)
set(sdl2_image_export_name SDL2_image)
set(sdl2_image_install_name_infix shared)
+ set(sdl2_target_name SDL2::SDL2)
else()
set(sdl2_image_export_name SDL2_image-static)
set(sdl2_image_install_name_infix static)
+ set(sdl2_target_name SDL2::SDL2-static)
+endif()
+
+sdl_find_sdl2(${sdl2_target_name} ${SDL_REQUIRED_VERSION})
+
+# Set PROJECT_VERSION of subprojects to "" if it's project call does not set VERSION
+cmake_policy(SET CMP0048 NEW)
+
+# Allow 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()
add_library(SDL2_image
IMG.c
+ IMG_WIC.c
IMG_avif.c
IMG_bmp.c
IMG_gif.c
@@ -324,74 +184,157 @@ add_library(SDL2_image
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::${sdl2_image_export_name} ALIAS SDL2_image)
-
+target_include_directories(SDL2_image PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>"
+)
target_compile_definitions(SDL2_image PRIVATE
SDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION}
SDL_BUILD_MINOR_VERSION=${MINOR_VERSION}
SDL_BUILD_MICRO_VERSION=${MICRO_VERSION}
+)
+target_link_libraries(SDL2_image PRIVATE ${sdl2_target_name})
+if(WIN32 AND SDL2IMAGE_BUILD_SHARED_LIBS)
+ target_sources(SDL2_image PRIVATE
+ version.rc
+)
+endif()
+set_target_properties(SDL2_image PROPERTIES
+ DEFINE_SYMBOL DLL_EXPORT
+ PUBLIC_HEADER SDL_image.h
+ EXPORT_NAME ${sdl2_image_export_name}
+ C_VISIBILITY_PRESET "hidden"
+)
+if(NOT ANDROID)
+ set_target_properties(SDL2_image PROPERTIES
+ DEBUG_POSTFIX "${SDL2IMAGE_DEBUG_POSTFIX}"
)
+ if(APPLE)
+ # the SOVERSION property corresponds to the compatibility version and VERSION corresponds to the current version
+ # https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html#mach-o-versions
+ set_target_properties(SDL2_image PROPERTIES
+ SOVERSION "${DYLIB_COMPATIBILITY_VERSION}"
+ VERSION "${DYLIB_CURRENT_VERSION}"
+ )
+ else()
+ set_target_properties(SDL2_image PROPERTIES
+ SOVERSION "${LT_MAJOR}"
+ VERSION "${LT_VERSION}"
+ )
+ endif()
+endif()
+if(SDL2IMAGE_BUILD_SHARED_LIBS AND (APPLE OR (UNIX AND NOT ANDROID)))
+ add_custom_command(TARGET SDL2_image POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E create_symlink "$<TARGET_SONAME_FILE_NAME:SDL2_image>" "libSDL2_image$<$<CONFIG:Debug>:${SDL2IMAGE_DEBUG_POSTFIX}>$<TARGET_FILE_SUFFIX:SDL2_image>"
+ # BYPRODUCTS "libSDL2_image$<$<CONFIG:Debug>:${SDL2IMAGE_DEBUG_POSTFIX}>$<TARGET_FILE_SUFFIX:SDL2_image>" # Needs CMake 3.20
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
+ )
+endif()
+if(SDL2IMAGE_BUILD_SHARED_LIBS)
+ if(WIN32 OR OS2)
+ set_target_properties(SDL2_image PROPERTIES
+ PREFIX ""
+ )
+ endif()
+ if(OS2)
+ # OS/2 doesn't support a DLL name longer than 8 characters.
+ set_target_properties(SDL2_image PROPERTIES
+ OUTPUT_NAME "SDL2img"
+ )
+ elseif(UNIX AND NOT ANDROID)
+ set_target_properties(SDL2_image PROPERTIES
+ OUTPUT_NAME "SDL2_image-${LT_RELEASE}"
+ )
+ endif()
+endif()
+
+# Use `Compatible Interface Properties` to ensure all SDL2 libraries are built with the same "sharedness".
+set_property(TARGET SDL2_image PROPERTY INTERFACE_SDL2_SHARED ${SDL2IMAGE_BUILD_SHARED_LIBS})
+set_property(TARGET SDL2_image APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL2_SHARED)
+
+set(INSTALL_EXTRA_TARGETS)
+set(PC_LIBS)
+set(PC_REQUIRES)
-if (BACKEND_STB)
+if(SDL2IMAGE_BACKEND_STB)
target_compile_definitions(SDL2_image PRIVATE USE_STBIMAGE)
endif()
-if (APPLE)
- if (BACKEND_IMAGEIO)
+if(SDL2IMAGE_BUILD_SHARED_LIBS)
+ # Make sure static library dependencies are built with -fPIC when building a shared SDL2_image
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+endif()
+
+if(APPLE)
+ if(SDL2IMAGE_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()
-if (BACKEND_WIC)
+if(SDL2IMAGE_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
- )
+if(SDL2IMAGE_ZLIB_VENDORED)
+ message(STATUS "${PROJECT_NAME}: Using vendored zlib")
+ sdl_check_project_in_subfolder(external/zlib zlib)
+ add_subdirectory(external/zlib EXCLUDE_FROM_ALL)
+ # PNG_BUILD_ZLIB variable is used by vendored libpng
+ set(PNG_BUILD_ZLIB ON CACHE BOOL "libpng option to tell it should use 'our' vendored ZLIB library" FORCE)
+ # ZLIB_INCLUDE_DIR variable is used by vendored libpng
+ set(ZLIB_INCLUDE_DIR "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/zlib;${CMAKE_CURRENT_BINARY_DIR}/external/zlib>" CACHE STRING "path of zlib, passed to libpng" FORCE)
+ # ZLIB_LIBRARY variable is used by vendored libpng
+ if(SDL2IMAGE_ZLIB_SHARED)
+ set(ZLIB_LIBRARY zlib)
+ else()
+ set(ZLIB_LIBRARY zlibstatic)
+ endif()
+ list(APPEND INSTALL_EXTRA_TARGETS ${ZLIB_LIBRARY})
+else()
+ message(STATUS "${PROJECT_NAME}: Using system zlib")
+ find_package(ZLIB REQUIRED)
endif()
-set(INSTALL_EXTRA_TARGETS)
-set(PC_REQUIRES)
-set(PC_LIBS)
-
-if (SUPPORT_AVIF)
+if(SDL2IMAGE_AVIF)
target_compile_definitions(SDL2_image PRIVATE LOAD_AVIF)
- if (SUPPORT_AVIF_VENDORED)
-
(Patch may be truncated, please check the link at the top of this post.)