diff --git a/conan/export_libs.bat b/conan/export_libs.bat index ef34698..95a18d3 100755 --- a/conan/export_libs.bat +++ b/conan/export_libs.bat @@ -1,3 +1,4 @@ conan export %0/../libjuice/all/conanfile.py --version=1.6.1 conan export %0/../libdatachannel/all/conanfile.py --version=0.23.1 conan export %0/../conan-skia/recipes/skia/all/conanfile.py --version=134.20250327.0 +conan export %0/../sdl3/3.x/conanfile.py --version=3.2.24 diff --git a/conan/export_libs.sh b/conan/export_libs.sh index a4ea045..646ecea 100755 --- a/conan/export_libs.sh +++ b/conan/export_libs.sh @@ -6,5 +6,6 @@ conan export "$(dirname "$0")/libjuice/all/conanfile.py" --version=1.6.1 conan export "$(dirname "$0")/libdatachannel/all/conanfile.py" --version=0.23.1 conan export "$(dirname "$0")/mpg123/all/conanfile.py" --version=1.32.10 conan export "$(dirname "$0")/conan-skia/recipes/skia/all/conanfile.py" --version=134.20250327.0 +conan export "$(dirname "$0")/sdl3/3.x/conanfile.py" --version=3.2.24 #conan create . -o use_system_expat=False -o use_system_freetype=False -o use_system_harfbuzz=False -o use_system_icu=False -o use_system_libjpeg_turbo=False -o use_system_libpng=False -o use_system_libwebp=False -o use_system_zlib=False --build=missing --version=134.20250327.0 #cd ../../../.. diff --git a/conan/sdl3/3.x/conandata.yml b/conan/sdl3/3.x/conandata.yml new file mode 100644 index 0000000..c9450cd --- /dev/null +++ b/conan/sdl3/3.x/conandata.yml @@ -0,0 +1,4 @@ +sources: + "3.2.24": + url: "https://github.com/libsdl-org/SDL/releases/download/release-3.2.24/SDL3-3.2.24.tar.gz" + sha256: "81cc0fc17e5bf2c1754eeca9af9c47a76789ac5efdd165b3b91cbbe4b90bfb76" diff --git a/conan/sdl3/3.x/conanfile.py b/conan/sdl3/3.x/conanfile.py new file mode 100644 index 0000000..98dd7e9 --- /dev/null +++ b/conan/sdl3/3.x/conanfile.py @@ -0,0 +1,467 @@ +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os +from conan.tools.files import get, copy, replace_in_file, rmdir +from conan.tools.gnu import PkgConfigDeps +from conan.tools.microsoft import is_msvc +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout, CMakeDeps +import os + +required_conan_version = ">=2" + +_subsystems = [ + ("audio", []), + ("video", []), + ("gpu", ["video"]), + ("render", ["video"]), + ("camera", ["video"]), + ("joystick", []), + ("haptic", ["joystick"]), + ("hidapi", []), + ("power", []), + ("sensor", []), + ("dialog", []), +] + +class SDLConan(ConanFile): + name = "sdl" + description = "A cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware" + license = "Zlib" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://www.libsdl.org" + topics = ("sdl3", "audio", "keyboard", "graphics", "opengl") + package_type = "library" + settings = "os", "arch", "compiler", "build_type" + + options = { + **{ + "shared": [True, False], + "fPIC": [True, False], + }, + **{subsystem: [True, False] for subsystem, _ in _subsystems}, + **{ + "alsa": [True, False], + "pulseaudio": [True, False], + "sndio": [True, False], + "opengl": [True, False], + "opengles": [True, False], + "x11": [True, False], + "xcursor": [True, False], + "xdbe": [True, False], + "xinput": [True, False], + "xfixes": [True, False], + "xrandr": [True, False], + "xscrnsaver": [True, False], + "xshape": [True, False], + "xsync": [True, False], + "wayland": [True, False], + "vulkan": [True, False], + "metal": [True, False], + "directx": [True, False], + "libudev": [True, False], + "dbus": [True, False], + "libusb": [True, False], + "libiconv": [True, False], + } + } + + default_options = { + **{ + "shared": False, + "fPIC": True, + }, + **{subsystem: True for subsystem, _ in _subsystems}, + **{ + ## Audio + # Linux only + "alsa": True, + "pulseaudio": True, + "sndio": True, + ## Video + "opengl": True, + "opengles": True, + "x11": True, + "xcursor": True, + "xdbe": True, + "xinput": True, + "xfixes": True, + "xrandr": True, + "xscrnsaver": True, + "xshape": True, + "xsync": True, + "wayland": True, + "vulkan": True, + "metal": True, + "directx": True, + ## Hidapi + "libusb": False, + ## Other + "libudev": True, + "dbus": True, + "libiconv": False, + } + } + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + if not self._is_unix_sys: + del self.options.pulseaudio + del self.options.alsa + del self.options.sndio + del self.options.libudev + del self.options.dbus + del self.options.x11 + del self.options.xcursor + del self.options.xdbe + del self.options.xinput + del self.options.xfixes + del self.options.xrandr + del self.options.xscrnsaver + del self.options.xshape + del self.options.xsync + del self.options.wayland + + if not is_apple_os(self): + del self.options.metal + + if self.settings.os != "Windows": + del self.options.directx + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + + if not (self.settings.os == "Android" and self.options.get_safe("hidapi")): + self.settings.rm_safe("compiler.libcxx") + self.settings.rm_safe("compiler.cppstd") + + if not self.options.get_safe("audio"): + self.options.rm_safe("alsa") + self.options.rm_safe("pulseaudio") + self.options.rm_safe("sndio") + + if not self.options.get_safe("video"): + self.options.rm_safe("opengl") + self.options.rm_safe("opengles") + self.options.rm_safe("x11") + self.options.rm_safe("wayland") + self.options.rm_safe("vulkan") + self.options.rm_safe("metal") + + if not self.options.get_safe("x11"): + self.options.rm_safe("xcursor") + self.options.rm_safe("xdbe") + self.options.rm_safe("xinput") + self.options.rm_safe("xfixes") + self.options.rm_safe("xrandr") + self.options.rm_safe("xscrnsaver") + self.options.rm_safe("xshape") + self.options.rm_safe("xsync") + + if not self.options.get_safe("hidapi") or self.settings.os in ["Android", "iOS", "tvOS", "visionOS", "watchOS"]: + # libusb is only an option if hidapi is enabled: https://github.com/libsdl-org/SDL/blob/db3a35e9bc3aa245dfbe67585b3f67d7b4b62845/cmake/sdlchecks.cmake#L1111 + # libusb is not available on Android/iOS/tvOS/visionOS/watchOS https://github.com/libsdl-org/SDL/blob/db3a35e9bc3aa245dfbe67585b3f67d7b4b62845/CMakeLists.txt#L159-L160 + self.options.rm_safe("libusb") + + def validate(self): + # If any of the subsystems is enabled, then the corresponding dependencies must be enabled + for subsystem, dependencies in _subsystems: + if self.options.get_safe(subsystem): + for dependency in dependencies: + if not self.options.get_safe(dependency): + raise ConanInvalidConfiguration(f'-o="&:{subsystem}=True" subsystem requires -o="&:{dependency}=True"') + + def validate_build(self): + if self.settings.os == "Android" and not self.conf.get("user.sdl:android", False): + raise ConanInvalidConfiguration("SDL builds on android require extra configuration on the user's side. " + "Set -c user.sdl:android=True if you understand it and want to build it") + + def layout(self): + cmake_layout(self, src_folder="src") + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + # Prevent inspecting target properties for libusb to derive the name of the .so/.dll + # instead, just link the library normally, see + # https://github.com/libsdl-org/SDL/blob/96292a5b464258a2b926e0a3d72f8b98c2a81aa6/cmake/sdlchecks.cmake#L1107-L1113 + replace_in_file(self, os.path.join(self.source_folder, "cmake", "sdlchecks.cmake"), + "target_get_dynamic_library(dynamic_libusb", "#target_get_dynamic_library(dynamic_libusb") + + @property + def _is_unix_sys(self): + """ True for UNIX but not Macos/Android""" + return self.settings.os in ("Linux", "FreeBSD") + + @property + def _supports_opengl(self): + return (self.options.get_safe("opengl") + and self.settings.os not in ("iOS", "visionOS", "tvOS", "watchOS")) + + @property + def _supports_opengles(self): + return (self.options.get_safe("opengles") + and self.settings.os in ("Android", "iOS", "visionOS", "tvOS", "watchOS")) + + @property + def _supports_dbus(self): + return self.options.get_safe("dbus") and self._is_unix_sys + + def requirements(self): + if self.options.get_safe("libiconv"): + self.requires("libiconv/1.17") + if self.options.get_safe("libusb"): + self.requires("libusb/1.0.26") + if self._supports_opengl: + self.requires("opengl/system") + if self.options.get_safe("libudev"): + self.requires("libudev/system") + if self._supports_dbus: + self.requires("dbus/1.15.8") + if self.options.get_safe("pulseaudio"): + self.requires("pulseaudio/17.0") + if self.options.get_safe("alsa"): + self.requires("libalsa/[>=1.2 <1.3]") + if self.options.get_safe("sndio"): + self.requires("libsndio/1.9.0") + if self.options.get_safe("wayland"): + self.requires("wayland/1.22.0") + self.requires("xkbcommon/1.6.0") + self.requires("egl/system") + if self.options.get_safe("x11"): + self.requires("xorg/system") + + def build_requirements(self): + self.tool_requires("cmake/[>=3.24 <4]") + if self._is_unix_sys and not self.conf.get("tools.gnu:pkg_config", check_type=str): + self.tool_requires("pkgconf/[>=2.2 <3]") + if self.options.get_safe("wayland"): + self.tool_requires("wayland/") # Provides wayland-scanner + + def generate(self): + tc = CMakeToolchain(self) + tc.cache_variables["SDL_SHARED"] = self.options.shared + tc.cache_variables["SDL_STATIC"] = not self.options.shared + tc.cache_variables["SDL_TEST_LIBRARY"] = False + tc.cache_variables["SDL_TESTS"] = False + tc.cache_variables["SDL_EXAMPLES"] = False + tc.cache_variables["SDL_INSTALL_EXAMPLES"] = False + tc.cache_variables["CMAKE_TRY_COMPILE_CONFIGURATION"] = str(self.settings.build_type) + tc.cache_variables["SDL_SYSTEM_ICONV_DEFAULT"] = True + tc.cache_variables["SDL_LIBICONV"] = self.options.libiconv + + tc.cache_variables["SDL_JACK"] = False # Jack is not available in CCI + + for subsystem in _subsystems: + tc.cache_variables[f"SDL_{subsystem[0].upper()}"] = self.options.get_safe(subsystem[0]) + + if self._supports_opengl: + tc.cache_variables["SDL_OPENGL"] = True + if self._supports_opengles: + tc.cache_variables["SDL_OPENGLES"] = True + + if self.options.hidapi: + tc.cache_variables["SDL_HIDAPI_LIBUSB"] = self.options.get_safe("libusb") + # Prevent loading shared libusb during runtime + # This just means it will be linked traditionally, even when libusb is shared + # See https://github.com/libsdl-org/SDL/blob/96292a5b464258a2b926e0a3d72f8b98c2a81aa6/cmake/sdlchecks.cmake#L1107-L1113 + tc.cache_variables["SDL_HIDAPI_LIBUSB_SHARED"] = False + + tc.variables["SDL_VULKAN"] = self.options.get_safe("vulkan") + tc.variables["SDL_METAL"] = self.options.get_safe("metal") + tc.variables["SDL_DIRECTX"] = self.options.get_safe("directx") + + if self.options.get_safe("pulseaudio"): + tc.cache_variables["SDL_PULSEAUDIO"] = True + tc.cache_variables["SDL_PULSEAUDIO_SHARED"] = self.dependencies["pulseaudio"].options.get_safe("shared", True) + if self.options.get_safe("alsa"): + tc.cache_variables["SDL_ALSA"] = True + tc.cache_variables["SDL_ALSA_SHARED"] = self.dependencies["libalsa"].options.shared + if self.options.get_safe("sndio"): + tc.cache_variables["SDL_SNDIO"] = True + tc.cache_variables["SDL_SNDIO_SHARED"] = True # sndio is always shared + tc.cache_variables["SDL_LIBUDEV"] = self.options.get_safe("libudev", False) + + # X11 and wayland configuration + with_x11 = self.options.get_safe("x11", False) + tc.cache_variables["SDL_X11"] = with_x11 + tc.cache_variables["SDL_X11_SHARED"] = True + if with_x11: + # See https://github.com/bincrafters/community/issues/696 + tc.cache_variables["SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS"] = 1 + tc.cache_variables["SDL_X11_XCURSOR"] = self.options.xcursor + tc.cache_variables["SDL_X11_XDBE"] = self.options.xdbe + tc.cache_variables["SDL_X11_XINPUT"] = self.options.xinput + tc.cache_variables["SDL_X11_XFIXES"] = self.options.xfixes + tc.cache_variables["SDL_X11_XRANDR"] = self.options.xrandr + tc.cache_variables["SDL_X11_XSCRNSAVER"] = self.options.xscrnsaver + tc.cache_variables["SDL_X11_XSHAPE"] = self.options.xshape + tc.cache_variables["SDL_X11_XSYNC"] = self.options.xsync + + with_wayland = self.options.get_safe("wayland", False) + tc.cache_variables["SDL_WAYLAND"] = with_wayland + if with_wayland: + tc.cache_variables["SDL_WAYLAND_SHARED"] = self.dependencies["wayland"].options.shared + if not with_x11 and not with_wayland: + # Disable windowing support: + # https://github.com/libsdl-org/SDL/blob/main/docs/README-cmake.md#cmake-fails-to-build-without-x11-or-wayland-support + tc.cache_variables["SDL_UNIX_CONSOLE_BUILD"] = True + + tc.generate() + deps = CMakeDeps(self) + deps.set_property("libusb", "cmake_target_name", "LibUSB::LibUSB") + deps.set_property("libusb", "cmake_file_name", "LibUSB") + deps.generate() + pcdeps = PkgConfigDeps(self) + pcdeps.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + copy(self, "LICENSE.txt", self.source_folder, os.path.join(self.package_folder, "licenses")) + cmake = CMake(self) + cmake.install() + rmdir(self, os.path.join(self.package_folder, "cmake")) + rmdir(self, os.path.join(self.package_folder, "lib", "cmake")) + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + + @property + def _is_clang_cl(self): + return self.settings.os == "Windows" and self.settings.compiler == "clang" and \ + self.settings.compiler.get_safe("runtime") + + def package_info(self): + self.cpp_info.set_property("cmake_file_name", "SDL3") + + sdl_lib_name = "SDL3" + if (is_msvc(self) or self._is_clang_cl) and not self.options.shared: + sdl_lib_name = f"{sdl_lib_name}-static" + self.cpp_info.components["sdl3"].libs = [sdl_lib_name] + self.cpp_info.components["sdl3"].set_property("cmake_target_name", "SDL3::SDL3") + self.cpp_info.components["sdl3"].set_property("cmake_target_aliases", [ + "SDL3::SDL3-shared" if self.options.shared else "SDL3::SDL3-static", + ]) + + # Target that only contains the include directories + self.cpp_info.components["headers"].set_property("cmake_target_name", "SDL3::Headers") + self.cpp_info.components["headers"].libdirs = [] + + self.cpp_info.components["sdl3"].requires.append("headers") + + if self.settings.os in ("Linux", "FreeBSD", "Macos"): + self.cpp_info.components["sdl3"].system_libs.append("pthread") + + if self.options.get_safe("libiconv"): + self.cpp_info.components["sdl3"].requires.append("libiconv::libiconv") + + if self.options.get_safe("libudev"): + self.cpp_info.components["sdl3"].requires.append("libudev::libudev") + + if self.options.get_safe("libusb"): + self.cpp_info.components["sdl3"].requires.append("libusb::libusb") + + if self.options.get_safe("dbus"): + self.cpp_info.components["sdl3"].requires.append("dbus::dbus") + + if self.options.get_safe("opengl"): + self.cpp_info.components["sdl3"].requires.append("opengl::opengl") + + if self.options.get_safe("wayland"): + self.cpp_info.components["sdl3"].requires.extend(["wayland::wayland", "xkbcommon::xkbcommon", "egl::egl"]) + + if self.options.get_safe("x11"): + self.cpp_info.components["sdl3"].requires.extend(["xorg::x11", "xorg::xext"]) + # xdbe, xshape and xsync are covered by x11 and xext + if self.options.xcursor: + self.cpp_info.components["sdl3"].requires.append("xorg::xcursor") + if self.options.xinput: + self.cpp_info.components["sdl3"].requires.append("xorg::xi") + if self.options.xfixes: + self.cpp_info.components["sdl3"].requires.append("xorg::xfixes") + if self.options.xrandr: + self.cpp_info.components["sdl3"].requires.append("xorg::xrandr") + if self.options.xscrnsaver: + self.cpp_info.components["sdl3"].requires.append("xorg::xscrnsaver") + + if self.options.get_safe("audio"): + if self.options.get_safe("alsa"): + self.cpp_info.components["sdl3"].requires.append("libalsa::libalsa") + if self.options.get_safe("pulseaudio"): + self.cpp_info.components["sdl3"].requires.append("pulseaudio::pulseaudio") + if self.options.get_safe("sndio"): + self.cpp_info.components["sdl3"].requires.append("libsndio::libsndio") + + if self.settings.os == "Android": + if self.options.get_safe("video"): + self.cpp_info.components["sdl3"].system_libs.extend(["dl", "log", "android"]) + if self.options.get_safe("opengles"): + self.cpp_info.components["sdl3"].system_libs.extend(["GLESv1_CM", "GLESv2"]) + if self.options.get_safe("audio"): + self.cpp_info.components["sdl3"].system_libs.append("OpenSLES") + + # TODO(conan client): when shared, SDL do not need to link against its dependencies but conan will complain about it + if is_apple_os(self) and not self.options.shared: + self.cpp_info.components["sdl3"].frameworks = ["CoreVideo", "Foundation"] + + if self.settings.os == "Macos": + self.cpp_info.components["sdl3"].frameworks.extend(["Cocoa", "Carbon"]) + + if self.options.get_safe("audio"): + self.cpp_info.components["sdl3"].frameworks.extend(["CoreAudio", "AudioToolbox", "AVFoundation"]) + + if self.options.get_safe("video"): + if self.settings.os in ("iOS", "tvOS", "visionOS", "watchOS"): + self.cpp_info.components["sdl3"].frameworks.extend(["CoreGraphics", "QuartzCore", "UIKit"]) + else: + self.cpp_info.components["sdl3"].frameworks.append("UniformTypeIdentifiers") + + if self.options.get_safe("camera"): + if self.settings.os in ("Macos", "iOS"): + self.cpp_info.components["sdl3"].frameworks.append("CoreMedia") + self.cpp_info.components["sdl3"].frameworks.append("AVFoundation") + + if self.options.get_safe("joystick"): + self.cpp_info.components["sdl3"].frameworks.append("GameController") + self.cpp_info.components["sdl3"].sharedlinkflags.append("-Wl,-weak_framework,CoreHaptics") + self.cpp_info.components["sdl3"].exelinkflags.append("-Wl,-weak_framework,CoreHaptics") + if self.settings.os == "Macos": + # Mind that ForceFeedback is also added in haptic system, but haptic depends on joystick + self.cpp_info.components["sdl3"].frameworks.extend(["ForceFeedback", "IOKit"]) + elif self.settings.os in ("iOS", "visionOS", "watchOS"): + self.cpp_info.components["sdl3"].frameworks.append("CoreMotion") + + if self.options.get_safe("hidapi") and self.settings.os in ("iOS", "tvOS"): + self.cpp_info.components["sdl3"].frameworks.append("CoreBluetooth") + + if self.options.get_safe("power") and self.settings.os == "Macos": + self.cpp_info.components["sdl3"].frameworks.append("IOKit") + + if self.options.get_safe("opengles") and self.settings.os in ("iOS", "tvOS", "visionOS", "watchOS"): + self.cpp_info.components["sdl3"].frameworks.append("OpenGLES") + + if self.options.get_safe("metal"): + self.cpp_info.components["sdl3"].frameworks.extend(["Metal", "QuartzCore"]) + + # Windows links with all libs by default + if self.settings.os == "Windows": + self.cpp_info.components["sdl3"].system_libs.extend( + [ + "kernel32", + "user32", + "gdi32", + "winmm", + "imm32", + "ole32", + "oleaut32", + "version", + "uuid", + "advapi32", + "setupapi", + "shell32", + ] + ) diff --git a/conan/sdl3/3.x/test_package/CMakeLists.txt b/conan/sdl3/3.x/test_package/CMakeLists.txt new file mode 100644 index 0000000..52d1454 --- /dev/null +++ b/conan/sdl3/3.x/test_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package) + +find_package(SDL3 REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} SDL3::SDL3) + diff --git a/conan/sdl3/3.x/test_package/conanfile.py b/conan/sdl3/3.x/test_package/conanfile.py new file mode 100644 index 0000000..c21bd20 --- /dev/null +++ b/conan/sdl3/3.x/test_package/conanfile.py @@ -0,0 +1,31 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) + + def generate(self): + tc = CMakeToolchain(self) + tc.generate() + + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/conan/sdl3/3.x/test_package/test_package.cpp b/conan/sdl3/3.x/test_package/test_package.cpp new file mode 100644 index 0000000..b9d1f23 --- /dev/null +++ b/conan/sdl3/3.x/test_package/test_package.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char* args[]) { + auto version = SDL_GetVersion(); + std::cout << "SDL version " << version << std::endl; + return 0; +} diff --git a/conan/sdl3/all/conandata.yml b/conan/sdl3/all/conandata.yml new file mode 100644 index 0000000..2c00cce --- /dev/null +++ b/conan/sdl3/all/conandata.yml @@ -0,0 +1,4 @@ +sources: + "2.32.10": + url: "https://www.libsdl.org/release/SDL2-2.32.10.tar.gz" + sha256: "5f5993c530f084535c65a6879e9b26ad441169b3e25d789d83287040a9ca5165" diff --git a/conan/sdl3/all/conanfile.py b/conan/sdl3/all/conanfile.py new file mode 100644 index 0000000..e4e2883 --- /dev/null +++ b/conan/sdl3/all/conanfile.py @@ -0,0 +1,431 @@ +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os +from conan.tools.files import get, replace_in_file, rm, rmdir, copy +from conan.tools.microsoft import is_msvc +from conan.tools.scm import Version +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.env import Environment + +import os + +required_conan_version = ">=2.1" + + +class SDLConan(ConanFile): + name = "sdl" + description = "Access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL, Direct3D and Vulkan" + license = "Zlib" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://www.libsdl.org" + topics = ("sdl2", "audio", "keyboard", "graphics", "opengl") + package_type = "library" + settings = "os", "arch", "compiler", "build_type" + options = { + "shared": [True, False], + "fPIC": [True, False], + "directx": [True, False], + "alsa": [True, False], + "jack": [True, False], + "pulse": [True, False], + "sndio": [True, False], + "nas": [True, False], + "esd": [True, False], + "arts": [True, False], + "x11": [True, False], + "xcursor": [True, False], + "xinerama": [True, False], + "xinput": [True, False], + "xrandr": [True, False], + "xscrnsaver": [True, False], + "xshape": [True, False], + "xvm": [True, False], + "wayland": [True, False], + "directfb": [True, False], + "iconv": [True, False], + "video_rpi": [True, False], + "sdl2main": [True, False], + "opengl": [True, False], + "opengles": [True, False], + "vulkan": [True, False], + "libunwind": [True, False], + "hidapi": [True, False], + } + default_options = { + "shared": False, + "fPIC": True, + "directx": True, + "alsa": True, + "jack": False, + "pulse": True, + "sndio": False, + "nas": False, + "esd": False, + "arts": False, + "x11": True, + "xcursor": True, + "xinerama": True, + "xinput": True, + "xrandr": True, + "xscrnsaver": True, + "xshape": True, + "xvm": True, + "wayland": True, + "directfb": False, + "video_rpi": False, + "sdl2main": True, + "opengl": True, + "opengles": True, + "vulkan": True, + "libunwind": True, + "hidapi": True, + } + generators = "CMakeDeps", "PkgConfigDeps", "VirtualBuildEnv" + + @property + def _is_clang_cl(self): + return self.settings.os == "Windows" and self.settings.compiler == "clang" and \ + self.settings.compiler.get_safe("runtime") + + def layout(self): + cmake_layout(self, src_folder="src") + + def generate(self): + self.define_toolchain() + lib_paths = [lib for _, dep in self.dependencies.items() for lib in dep.cpp_info.libdirs] + env = Environment() + env.define_path("LIBRARY_PATH", os.pathsep.join(lib_paths)) + + env = env.vars(self, scope="build") + env.save_script("sdl_env") + + def config_options(self): + # Don't depend on iconv on Apple by default + # SDL2 depends on many system freamworks, + # which depend on the system-provided iconv + # and can conflict with the Conan provided one + self.options.iconv = not is_apple_os(self) + + if self.settings.os == "Windows": + del self.options.fPIC + if (is_msvc(self) or self._is_clang_cl): + del self.options.iconv + if self.settings.os != "Linux": + del self.options.alsa + del self.options.jack + del self.options.pulse + del self.options.sndio + del self.options.nas + del self.options.esd + del self.options.arts + del self.options.x11 + del self.options.xcursor + del self.options.xinerama + del self.options.xinput + del self.options.xrandr + del self.options.xscrnsaver + del self.options.xshape + del self.options.xvm + del self.options.wayland + del self.options.directfb + del self.options.video_rpi + del self.options.libunwind + if self.settings.os != "Windows": + del self.options.directx + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + # TODO: C++ is also required for WinRT and Haiku + if not (self.settings.os == "Android" and self.options.hidapi): + self.settings.rm_safe("compiler.libcxx") + self.settings.rm_safe("compiler.cppstd") + + def requirements(self): + if self.options.get_safe("iconv", False): + self.requires("libiconv/1.17") + if self.settings.os == "Linux": + if self.options.alsa: + self.requires("libalsa/1.2.10") + if self.options.pulse: + self.requires("pulseaudio/14.2") + if self.options.opengl: + self.requires("opengl/system") + if self.options.nas: + self.requires("nas/1.9.5") + if self.options.wayland: + self.requires("wayland/1.22.0") + self.requires("xkbcommon/1.6.0") + self.requires("egl/system") + if self.options.libunwind: + self.requires("libunwind/1.8.0") + + def validate(self): + # SDL>=2.0.18 requires xcode 12 or higher because it uses CoreHaptics. + if is_apple_os(self) and Version(self.settings.compiler.version) < "12": + raise ConanInvalidConfiguration("{}/{} requires xcode 12 or higher".format(self.name, self.version)) + + if self.settings.os == "Linux": + if self.options.sndio: + raise ConanInvalidConfiguration("Package for 'sndio' is not available (yet)") + if self.options.jack: + raise ConanInvalidConfiguration("Package for 'jack' is not available (yet)") + if self.options.esd: + raise ConanInvalidConfiguration("Package for 'esd' is not available (yet)") + if self.options.directfb: + raise ConanInvalidConfiguration("Package for 'directfb' is not available (yet)") + + def build_requirements(self): + self.tool_requires("cmake/[>3.27 <4]") + if self.settings.os == "Linux" and not self.conf.get("tools.gnu:pkg_config", check_type=str): + self.tool_requires("pkgconf/2.1.0") + if hasattr(self, "settings_build") and self.options.get_safe("wayland"): + self.build_requires("wayland/1.22.0") # Provides wayland-scanner + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def _patch_sources(self): + # Ensure to find wayland-scanner from wayland recipe in build requirements (or requirements if 1 profile) + if self.options.get_safe("wayland"): + replace_in_file(self, + os.path.join(self.source_folder, "cmake", "sdlchecks.cmake"), + "find_program(WAYLAND_SCANNER NAMES wayland-scanner REQUIRED)", + 'find_program(WAYLAND_SCANNER NAMES wayland-scanner REQUIRED PATHS "${WAYLAND_BIN_DIR}" NO_DEFAULT_PATH)', + ) + if not self.options.shared: + replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"), "list(APPEND targets SDL2-static)", "set(targets SDL2-static)") + + def define_toolchain(self): + tc = CMakeToolchain(self) + if self.settings.os == "Linux" and self.settings.compiler == "gcc" and Version(self.settings.compiler.version) < 5.0: + tc.preprocessor_definitions["GBM_BO_USE_CURSOR"] = 2 + + tc.variables["SDL2_DISABLE_INSTALL"] = False # SDL2_* options will get renamed to SDL_ options in the next SDL release + if is_apple_os(self): + tc.variables["CMAKE_OSX_ARCHITECTURES"] = { + "armv8": "arm64", + }.get(str(self.settings.arch), str(self.settings.arch)) + cmake_required_includes = [] # List of directories used by CheckIncludeFile (https://cmake.org/cmake/help/latest/module/CheckIncludeFile.html) + cmake_extra_ldflags = [] + cmake_extra_libs = [] + + if self.settings.os != "Windows" and not self.options.shared: + tc.variables["SDL_STATIC_PIC"] = self.options.fPIC + if (is_msvc(self) or self._is_clang_cl) and not self.options.shared: + tc.variables["HAVE_LIBC"] = True + tc.variables["SDL_SHARED"] = self.options.shared + tc.variables["SDL_STATIC"] = not self.options.shared + tc.variables["SDL_TEST"] = False + tc.variables["SDL_OPENGL"] = self.options.opengl + tc.variables["SDL_OPENGLES"] = self.options.opengles + tc.variables["SDL_VULKAN"] = self.options.vulkan + tc.variables["SDL_HIDAPI"] = self.options.hidapi + if self.settings.os == "Linux": + # See https://github.com/bincrafters/community/issues/696 + tc.variables["SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS"] = 1 + + tc.variables["SDL_ALSA"] = self.options.alsa + if self.options.alsa: + tc.variables["SDL_ALSA_SHARED"] = self.dependencies["libalsa"].options.shared + tc.variables["HAVE_ASOUNDLIB_H"] = True + tc.variables["HAVE_LIBASOUND"] = True + tc.variables["SDL_JACK"] = self.options.jack + if self.options.jack: + tc.variables["SDL_JACK_SHARED"] = self.options["jack"].shared + tc.variables["SDL_ESD"] = self.options.esd + if self.options.esd: + tc.variables["SDL_ESD_SHARED"] = self.options["esd"].shared + tc.variables["SDL_PULSEAUDIO"] = self.options.pulse + if self.options.pulse: + tc.variables["SDL_PULSEAUDIO_SHARED"] = self.dependencies["pulseaudio"].options.shared + for component in self.dependencies["pulseaudio"].cpp_info.components: + if self.dependencies["pulseaudio"].cpp_info.components[component].libs: + cmake_extra_libs += self.dependencies["pulseaudio"].cpp_info.components[component].libs + cmake_extra_ldflags += ["-L{}".format(it) for it in self.dependencies["pulseaudio"].cpp_info.components[component].libdirs] + cmake_extra_ldflags += ["-lxcb", "-lrt"] # FIXME: SDL sources doesn't take into account transitive dependencies + tc.variables["SDL_SNDIO"] = self.options.sndio + if self.options.sndio: + tc.variables["SDL_SNDIO_SHARED"] = self.options["sndio"].shared + tc.variables["SDL_NAS"] = self.options.nas + if self.options.nas: + cmake_extra_ldflags += ["-lXau"] # FIXME: SDL sources doesn't take into account transitive dependencies + cmake_required_includes += self.dependencies["nas"].cpp_info.includedirs + tc.variables["SDL_NAS_SHARED"] = self.dependencies["nas"].options.shared + tc.variables["SDL_X11"] = self.options.x11 + if self.options.x11: + tc.variables["HAVE_XEXT_H"] = True + tc.variables["SDL_X11_XCURSOR"] = self.options.xcursor + if self.options.xcursor: + tc.variables["HAVE_XCURSOR_H"] = True + tc.variables["SDL_X11_XINERAMA"] = self.options.xinerama + if self.options.xinerama: + tc.variables["HAVE_XINERAMA_H"] = True + tc.variables["SDL_X11_XINPUT"] = self.options.xinput + if self.options.xinput: + tc.variables["HAVE_XINPUT_H"] = True + tc.variables["SDL_X11_XRANDR"] = self.options.xrandr + if self.options.xrandr: + tc.variables["HAVE_XRANDR_H"] = True + tc.variables["SDL_X11_XSCRNSAVER"] = self.options.xscrnsaver + if self.options.xscrnsaver: + tc.variables["HAVE_XSS_H"] = True + tc.variables["SDL_X11_XSHAPE"] = self.options.xshape + if self.options.xshape: + tc.variables["HAVE_XSHAPE_H"] = True + tc.variables["SDL_X11_XVM"] = self.options.xvm + if self.options.xvm: + tc.variables["HAVE_XF86VM_H"] = True + tc.variables["SDL_WAYLAND"] = self.options.wayland + if self.options.wayland: + # FIXME: Otherwise 2.0.16 links with system wayland (from egl/system requirement) + cmake_extra_ldflags += ["-L{}".format(it) for it in self.dependencies["wayland"].cpp_info.libdirs] + tc.variables["SDL_WAYLAND_SHARED"] = self.dependencies["wayland"].options.shared + + wayland = self.dependencies["wayland"] if not hasattr(self, "settings_build") else self.dependencies.build["wayland"] + wayland_bin_dir = wayland.cpp_info.bindirs[0] # for wayland scanner + tc.variables["WAYLAND_BIN_DIR"] = wayland_bin_dir + + tc.variables["SDL_DIRECTFB"] = self.options.directfb + tc.variables["SDL_RPI"] = self.options.video_rpi + tc.variables["HAVE_LIBUNWIND_H"] = self.options.libunwind + elif self.settings.os == "Windows": + tc.variables["SDL_DIRECTX"] = self.options.directx + + tc.variables["SDL2_DISABLE_SDL2MAIN"] = not self.options.sdl2main + tc.variables["SDL_LIBICONV"] = self.options.get_safe("iconv", False) + tc.variables["SDL_SYSTEM_ICONV"] = False + + # Add extra information collected from the deps + tc.variables["EXTRA_LDFLAGS"] = ";".join(cmake_extra_ldflags) + tc.variables["CMAKE_REQUIRED_INCLUDES"] = ";".join(cmake_required_includes) + cmake_extra_cflags = ["-I{}".format(path) for _, dep in self.dependencies.items() for path in dep.cpp_info.includedirs] + tc.variables["EXTRA_CFLAGS"] = ";".join(cmake_extra_cflags).replace(os.sep, '/') + tc.variables["EXTRA_LIBS"] = ";".join(cmake_extra_libs) + tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW" + tc.generate() + + def build(self): + self._patch_sources() + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + + copy(self, pattern="LICENSE.txt", src=os.path.join(self.source_folder), dst=os.path.join(self.package_folder, "licenses")) + rm(self, "sdl2-config", os.path.join(self.package_folder, "bin")) + rm(self, "*.pdb", os.path.join(self.package_folder, "lib")) + rm(self, "*.pdb", os.path.join(self.package_folder, "bin")) + rmdir(self, os.path.join(self.package_folder, "cmake")) + rmdir(self, os.path.join(self.package_folder, "lib", "cmake")) + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + rmdir(self, os.path.join(self.package_folder, "libdata")) + rmdir(self, os.path.join(self.package_folder, "share")) + if self.settings.os == "Android": + copy(self, pattern="*", + src=os.path.join(self.source_folder, "android-project", "app", "src", "main", "java"), + dst=os.path.join(self.package_folder, "share", "java", "SDL2")) + + def package_info(self): + self.cpp_info.set_property("cmake_file_name", "SDL2") + + postfix = "d" if self.settings.os != "Android" and self.settings.build_type == "Debug" else "" + + # SDL2 + lib_postfix = postfix + if (is_msvc(self) or self._is_clang_cl) and not self.options.shared: + lib_postfix = "-static" + postfix + + self.cpp_info.components["libsdl2"].set_property("cmake_target_name", "SDL2::SDL2") + if not self.options.shared: + self.cpp_info.components["libsdl2"].set_property("cmake_target_aliases", ["SDL2::SDL2-static"]) + self.cpp_info.components["libsdl2"].set_property("pkg_config_name", "sdl2") + + self.cpp_info.components["libsdl2"].includedirs.append(os.path.join("include", "SDL2")) + self.cpp_info.components["libsdl2"].libs = ["SDL2" + lib_postfix] + if self.options.get_safe("iconv", False): + self.cpp_info.components["libsdl2"].requires.append("libiconv::libiconv") + if self.settings.os == "Linux": + self.cpp_info.components["libsdl2"].system_libs = ["dl", "rt", "pthread"] + if self.options.alsa: + self.cpp_info.components["libsdl2"].requires.append("libalsa::libalsa") + if self.options.pulse: + self.cpp_info.components["libsdl2"].requires.append("pulseaudio::pulseaudio") + if self.options.opengl: + self.cpp_info.components["libsdl2"].requires.append("opengl::opengl") + if self.options.jack: + self.cpp_info.components["libsdl2"].requires.append("jack::jack") + if self.options.sndio: + self.cpp_info.components["libsdl2"].requires.append("sndio::sndio") + if self.options.nas: + self.cpp_info.components["libsdl2"].requires.append("nas::nas") + if self.options.esd: + self.cpp_info.components["libsdl2"].requires.append("esd::esd") + if self.options.directfb: + self.cpp_info.components["libsdl2"].requires.append("directfb::directfb") + if self.options.video_rpi: + self.cpp_info.components["libsdl2"].libs.append("bcm_host") + self.cpp_info.components["libsdl2"].includedirs.extend([ + "/opt/vc/include", + "/opt/vc/include/interface/vcos/pthreads", + "/opt/vc/include/interface/vmcs_host/linux" + ]) + self.cpp_info.components["libsdl2"].libdirs.append("/opt/vc/lib") + self.cpp_info.components["libsdl2"].sharedlinkflags.append("-Wl,-rpath,/opt/vc/lib") + self.cpp_info.components["libsdl2"].exelinkflags.append("-Wl,-rpath,/opt/vc/lib") + if self.options.wayland: + self.cpp_info.components["libsdl2"].requires.append("wayland::wayland") + self.cpp_info.components["libsdl2"].requires.append("xkbcommon::xkbcommon") + self.cpp_info.components["libsdl2"].requires.append("egl::egl") + if self.options.libunwind: + self.cpp_info.components["libsdl2"].requires.append("libunwind::libunwind") + elif is_apple_os(self) and not self.options.shared: + self.cpp_info.components["libsdl2"].frameworks = [ + "CoreVideo", "CoreAudio", "AudioToolbox", + "AVFoundation", "Foundation", "QuartzCore", + ] + if self.settings.os == "Macos": + self.cpp_info.components["libsdl2"].frameworks.extend([ + "Cocoa", + "Carbon", + "IOKit", + "ForceFeedback", + "CoreFoundation", + "CoreServices", + "AppKit" + ]) + self.cpp_info.components["libsdl2"].frameworks.append("GameController") + elif self.settings.os in ["iOS", "tvOS", "watchOS"]: + self.cpp_info.components["libsdl2"].frameworks.extend([ + "UIKit", "OpenGLES", "GameController", "CoreMotion", + "CoreGraphics", "CoreBluetooth", + ]) + + self.cpp_info.components["libsdl2"].frameworks.append("Metal") + self.cpp_info.components["libsdl2"].sharedlinkflags.append("-Wl,-weak_framework,CoreHaptics") + self.cpp_info.components["libsdl2"].exelinkflags.append("-Wl,-weak_framework,CoreHaptics") + elif self.settings.os == "Windows": + self.cpp_info.components["libsdl2"].system_libs = ["user32", "gdi32", "winmm", "imm32", "ole32", "oleaut32", "version", "uuid", "advapi32", "setupapi", "shell32"] + if self.settings.compiler == "gcc": + self.cpp_info.components["libsdl2"].system_libs.append("mingw32") + elif self.settings.os == "Android" and not self.options.shared: + self.cpp_info.components["libsdl2"].system_libs.extend(["android", "dl", "log"]) + if self.options.opengles: + self.cpp_info.components["libsdl2"].system_libs.extend(["GLESv1_CM", "GLESv2"]) + self.cpp_info.components["libsdl2"].system_libs.append("OpenSLES") + + # SDL2main + if self.options.sdl2main: + self.cpp_info.components["sdl2main"].set_property("cmake_target_name", "SDL2::SDL2main") + + self.cpp_info.components["sdl2main"].libs = ["SDL2main" + postfix] + self.cpp_info.components["sdl2main"].requires = ["libsdl2"] + + # Workaround to avoid unwanted sdl::sdl target in CMakeDeps generator + self.cpp_info.set_property( + "cmake_target_name", + "SDL2::{}".format("SDL2main" if self.options.sdl2main else "SDL2"), + ) diff --git a/conan/sdl3/all/test_package/CMakeLists.txt b/conan/sdl3/all/test_package/CMakeLists.txt new file mode 100644 index 0000000..4195ae0 --- /dev/null +++ b/conan/sdl3/all/test_package/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package) + +find_package(SDL2 REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} SDL2::SDL2main) +if(TARGET SDL2::SDL2-static) + target_link_libraries(${PROJECT_NAME} SDL2::SDL2-static) +else() + target_link_libraries(${PROJECT_NAME} SDL2::SDL2) +endif() + diff --git a/conan/sdl3/all/test_package/conanfile.py b/conan/sdl3/all/test_package/conanfile.py new file mode 100644 index 0000000..c21bd20 --- /dev/null +++ b/conan/sdl3/all/test_package/conanfile.py @@ -0,0 +1,31 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) + + def generate(self): + tc = CMakeToolchain(self) + tc.generate() + + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/conan/sdl3/all/test_package/test_package.cpp b/conan/sdl3/all/test_package/test_package.cpp new file mode 100644 index 0000000..69868e5 --- /dev/null +++ b/conan/sdl3/all/test_package/test_package.cpp @@ -0,0 +1,9 @@ +#include +#include + +int main(int argc, char* args[]) { + SDL_version v; + SDL_GetVersion(&v); + std::cout << "SDL version " << int(v.major) << "." << int(v.minor) << "." << int(v.patch) << std::endl; + return 0; +} diff --git a/conan/sdl3/config.yml b/conan/sdl3/config.yml new file mode 100644 index 0000000..ddeb6a9 --- /dev/null +++ b/conan/sdl3/config.yml @@ -0,0 +1,5 @@ +versions: + "3.2.24": + folder: 3.x + "2.32.10": + folder: all diff --git a/conanfile.py b/conanfile.py index bc3aac7..0e33acd 100644 --- a/conanfile.py +++ b/conanfile.py @@ -36,7 +36,7 @@ class CompressorRecipe(ConanFile): if self.settings.os == "Linux": - self.requires("sdl/3.2.20", options = { + self.requires("sdl/3.2.24", options = { "wayland": False, "pulseaudio": False, "alsa": False, @@ -45,7 +45,7 @@ class CompressorRecipe(ConanFile): "opengles": False }) else: - self.requires("sdl/3.2.20") + self.requires("sdl/3.2.24") if self.settings.os != "Emscripten" and self.settings.os != "Macos": self.requires("onetbb/2022.0.0") diff --git a/data/third_party_licenses/conan.io b/data/third_party_licenses/conan.io new file mode 100644 index 0000000..2b6d382 --- /dev/null +++ b/data/third_party_licenses/conan.io @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Conan.io + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/linuxinstall/com.infinipaint.infinipaint.yml b/linuxinstall/com.infinipaint.infinipaint.yml index ef66a90..3c190f4 100644 --- a/linuxinstall/com.infinipaint.infinipaint.yml +++ b/linuxinstall/com.infinipaint.infinipaint.yml @@ -45,7 +45,7 @@ modules: - -DSDL_X11=ON sources: - type: git - tag: release-3.2.20 + tag: release-3.2.24 url: https://github.com/libsdl-org/SDL.git - name: Skia buildsystem: simple