From 366beb30a4643c516b87b9433ebacc49f5460b7e Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 29 Jul 2026 06:17:17 +0800 Subject: [PATCH] feat: add compat.vulkan, sdl2, curl, glx-headers and vulkan-headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five packages behind the alternate GUI and network backends. They land together because each exercised the same class of problem — an upstream that generates its build configuration where this index wants a plain source list — and they are independently useful; nothing here depends on any consumer. compat.vulkan-headers 1.4.357.0 Khronos headers compat.vulkan 1.4.357.0 Khronos loader, from source (windows deferred) compat.curl 8.21.0 libcurl, OpenSSL / Schannel TLS compat.sdl2 2.32.10 SDL2 compat.glx-headers 1.7.0 libglvnd's GL/glx.h All five build from plain source lists: no CMake, no autotools, no install(). The Vulkan loader manages it because loader/generated/ is checked in and the GAS/MASM path is optional (UNKNOWN_FUNCTIONS_SUPPORTED gates it; upstream itself falls back to a pure-C implementation). curl and SDL manage it because both compile every unselected backend to an empty TU, so configuration lives entirely in a generated config header — needed only where upstream has a gap: unix for curl, linux for SDL, since both check in configs for the rest. compat.glx-headers fills a real hole: GL/glx.h is not in the Khronos OpenGL-Registry, so compat.opengl cannot supply it, and SDL's X11 driver does not build without it. compat.vulkan declares no windows entry. Upstream's only static-loader option is APPLE_STATIC_LOADER, gated to macOS with the warning that it "will only work on MacOS and is not supported" elsewhere; built anyway, the Windows loader links and then faults at the first entry point. This follows compat.openssl. CURL_STATICLIB needs to be always-on AND consumer-visible, and mcpp has no single key for that — cflags is always on but package-private, a feature's defines reach the consumer but need naming. `default = { implies = ... }` gives both: a default feature's own defines are inert, but what it implies is applied unconditionally (verified on 0.0.109 and 2026.7.29.1). tests/examples/curl does not define it and static_asserts that it arrived from the package; removing the default line makes that assertion fire. Verified cold on all three platforms. SDL2 is the one backend that genuinely runs headless — its dummy video driver executes SDL_Init, SDL_CreateWindow and a full event round-trip. Vulkan and curl are asserted on what is answerable without a GPU or a network; several near-misses there are recorded in the design doc, including a first draft that asserted on VK_KHR_surface and was really testing the runner's hardware. Windows and macOS each surfaced problems invisible on Linux, most notably that SDL2's tag archive carries POSIX symlinks and cannot be extracted on Windows — the package then installs empty, reports success, and every consumer fails with 'SDL.h' file not found. GLOBAL now points at a symlink-free repack on xlings-res/sdl2, following chriskohlhoff.asio. CN mirrors published to gitcode mcpp-res for all five, byte-identical. Design: .agents/docs/2026-07-29-add-gui-backend-packages-plan.md Co-authored-by: SPeak Agent <248744407+speak-agent@users.noreply.github.com> --- ...026-07-29-add-gui-backend-packages-plan.md | 193 ++++ README.md | 4 + mcpp.toml | 3 + pkgs/c/compat.curl.lua | 330 +++++++ pkgs/c/compat.glx-headers.lua | 80 ++ pkgs/c/compat.sdl2.lua | 923 ++++++++++++++++++ pkgs/c/compat.vulkan-headers.lua | 68 ++ pkgs/c/compat.vulkan.lua | 189 ++++ tests/examples/curl/mcpp.toml | 10 + tests/examples/curl/tests/transfer.cpp | 89 ++ tests/examples/sdl2/mcpp.toml | 6 + tests/examples/sdl2/tests/video.cpp | 95 ++ tests/examples/vulkan/mcpp.toml | 19 + tests/examples/vulkan/tests/loader.cpp | 77 ++ 14 files changed, 2086 insertions(+) create mode 100644 .agents/docs/2026-07-29-add-gui-backend-packages-plan.md create mode 100644 pkgs/c/compat.curl.lua create mode 100644 pkgs/c/compat.glx-headers.lua create mode 100644 pkgs/c/compat.sdl2.lua create mode 100644 pkgs/c/compat.vulkan-headers.lua create mode 100644 pkgs/c/compat.vulkan.lua create mode 100644 tests/examples/curl/mcpp.toml create mode 100644 tests/examples/curl/tests/transfer.cpp create mode 100644 tests/examples/sdl2/mcpp.toml create mode 100644 tests/examples/sdl2/tests/video.cpp create mode 100644 tests/examples/vulkan/mcpp.toml create mode 100644 tests/examples/vulkan/tests/loader.cpp diff --git a/.agents/docs/2026-07-29-add-gui-backend-packages-plan.md b/.agents/docs/2026-07-29-add-gui-backend-packages-plan.md new file mode 100644 index 0000000..6a8d7fd --- /dev/null +++ b/.agents/docs/2026-07-29-add-gui-backend-packages-plan.md @@ -0,0 +1,193 @@ +# Design doc: five packages behind the GUI/network backends + +Date: 2026-07-29 + +| package | version | what it is | +|---|---|---| +| `compat.vulkan-headers` | 1.4.357.0 | Khronos Vulkan headers | +| `compat.vulkan` | 1.4.357.0 | Khronos Vulkan loader, built from source | +| `compat.curl` | 8.21.0 | libcurl, OpenSSL on unix / Schannel on Windows | +| `compat.sdl2` | 2.32.10 | SDL2 | +| `compat.glx-headers` | 1.7.0 | libglvnd's `GL/glx.h` | + +They land together because they are what an alternate-backend GUI stack needs, and because +each one exercised the same class of problem: an upstream that generates its build +configuration, where this index wants a plain source list. They are independently useful — +nothing here depends on any consumer. + +All five build from plain source lists: no CMake, no autotools, no `install()` hook. + +## `compat.vulkan-headers` + `compat.vulkan` + +Split along upstream's own repository split. Headers are header-only (the `compat.opengl` +shape: include root plus an anchor TU). The loader is what a Vulkan program actually +links — `vkCreateInstance` and friends are loader trampolines dispatching into whatever ICD +the system advertises. + +**A plain source list works because two things happen to be true:** + +- `loader/generated/` (`vk_loader_extensions.c`, `vk_object_types.h`, …) is checked in + upstream, so CMake's codegen step is unnecessary. +- The assembly path is optional. Upstream compiles `dev_ext_trampoline.c` + + `phys_dev_ext.c` against hand-written GAS/MASM plus a `gen_defines.asm` that requires + building *and running* `asm_offset`, then scraping its output with Python. That chain is + gated on `UNKNOWN_FUNCTIONS_SUPPORTED`; upstream itself degrades when no assembler is + found and `unknown_function_handling.c` compiles a pure-C fallback. We take the fallback + deliberately — the cost is that unknown *device* extension entry points get no + trampoline, which nothing in this index uses. + +Two requirements only a real build surfaces: + +- `VK_ENABLE_BETA_EXTENSIONS` is mandatory despite the name: the checked-in + `vk_object_types.h` references `VK_OBJECT_TYPE_CUDA_MODULE_NV`, which the headers only + declare under it. Without it the loader does not compile at all. +- `SYSCONFDIR` / `FALLBACK_*_DIRS` must arrive as string literals, and + `-DSYSCONFDIR="/etc"` does not survive mcpp's flag splitting (mcpp#234): `loader.c` sees + a bare `/etc` and fails with *expected expression before '/' token*. They ride in a + force-included generated header instead. + +WSI is enabled per platform — Xlib + XCB on Linux (which makes `compat.x11` / `compat.xcb` +/ `compat.xorgproto` a **compile** dependency, since `vulkan_xlib.h` includes +``), Metal + MVK on macOS. Search paths are the FHS/XDG defaults because the +package must find the *host's* ICDs. + +### Windows is deferred + +A statically linked loader is not something upstream supports there: the only static option +in its CMake is `APPLE_STATIC_LOADER`, gated to macOS with the warning that it "will only +work on MacOS and is not supported" elsewhere. Built anyway, the Windows loader links and +then faults at the first entry point (0xC0000005 out of `vkEnumerateInstanceVersion`). +Linux is not covered by that option either, but a static loader is the ordinary case there +and works. Rather than ship a package that crashes, this follows `compat.openssl` and +declares no windows xpm entry; consumers gate with `[target.'cfg(...)']`. + +## `compat.curl` + +Full-source direct build, which works because curl compiles every unselected protocol and +TLS backend to an EMPTY translation unit (`vtls/gtls.c` is `#ifdef USE_GNUTLS` end to end). +The source list is plain globs; only `lib/dllmain.c` is excluded. + +The config header is the awkward part, and only on unix: `lib/config-win32.h` is checked in +and `curl_setup.h` selects it automatically when `HAVE_CONFIG_H` is absent, so Windows needs +nothing generated. linux/macosx get a generated `curl_config.h` branching on `__linux__` / +`__APPLE__`, with the Apple branch deliberately the conservative subset — an omitted +`HAVE_*` costs curl a fallback path, never correctness. + +Generating it against the *right* compiler mattered: a first pass with the host `cc` +produced a config asserting `ssize_t` did not exist (its probe failed for an unrelated +sysroot reason), and curl then failed to compile against its own config. + +TLS is OpenSSL on linux/macosx via `compat.openssl`, and Schannel on Windows — built into +the OS, and necessary because `compat.openssl` has no Windows build. + +### `CURL_STATICLIB`, and a use for an mcpp quirk + +`` declares everything `__declspec(dllimport)` unless `CURL_STATICLIB` is set, +so every Windows consumer of a static libcurl needs it — and no consumer should have to +know that. The define has to be **always on AND consumer-visible**, and mcpp has no single +key for that: `cflags` is always on but package-private, while a feature's `defines` reach +the consumer but need naming. + +`default = { implies = … }` is the combination that gives both. A default feature's own +`defines` are inert on mcpp (verified on 0.0.109 and 2026.7.29.1), but what it *implies* is +applied unconditionally — including when the consumer names some other feature. That is a +liability for expressing an exclusive choice; here "unconditionally on" is exactly right: + +```lua +features = { + ["default"] = { implies = { "staticlib" } }, + ["staticlib"] = { defines = { "CURL_STATICLIB" } }, +} +``` + +`tests/examples/curl` deliberately does **not** define it, and `static_assert`s that it +arrived from the package. Verified in both directions — deleting the `default` line makes +the assertion fire. + +## `compat.sdl2` and `compat.glx-headers` + +SDL is the mirror image of curl: upstream **checks in** `SDL_config_windows.h` and +`SDL_config_macosx.h` and dispatches to them from `include/SDL_config.h`; only Linux falls +through to `SDL_config_minimal.h`, which builds an SDL that can do essentially nothing. So +the generated header reproduces upstream's dispatch for windows/macosx and carries CMake's +Linux output inline. + +`compat.glx-headers` exists because SDL's X11 driver includes ``, and **no +package in this index had it** — `GL/glx.h` is not part of the Khronos OpenGL-Registry, so +`compat.opengl` cannot supply it. libglvnd is the canonical provider and is already named +as a wanted package in `2026-06-03-gl-runtime-packages-plan.md`. Headers only; +`compat.glx-runtime` still owns the runtime side. It overlaps `compat.opengl` on +`GL/gl.h`, so depend on one or the other, never both. + +## Things only CI could find + +Linux passed on the first try; every one of these was silent or misleading locally. + +- **SDL2's tag archive cannot be extracted on Windows.** Two POSIX symlinks under + `android-project-ant/`. The package then "installs" empty: reports success, compiles + nothing, exports no include dirs, and every consumer fails with `'SDL.h' file not found` + while the package itself never errors. `chriskohlhoff.asio` hit this and set the + precedent, so GLOBAL points at a symlink-free repack on `xlings-res/sdl2` with the + identical bytes mirrored to `mcpp-res`. Only the two symlink entries are removed. +- **SDL on Apple requires ARC.** Its cocoa classes declare `__weak SDL_WindowData *_data`, + and a `__weak` ivar without `-fobjc-arc` is rejected outright (`'_data' is unavailable`). + Upstream's CMake hard-fails when the compiler cannot do ARC, for this reason. +- **SDL on Windows needs `HAVE_LIBC`.** Upstream's config only sets it for `_MSC_VER`, and + this index builds with clang++, so SDL compiled its own `memcpy` and collided with + libvcruntime. +- **SDL's Windows condvar falls back to `thread/generic/SDL_syscond.c`** — but the rest of + `thread/generic` shares basenames with `thread/windows`, so only that one file can be + added. mcpp keys objects by basename in one flat per-link directory (mcpp#233), and + pulling the whole directory would have them silently displace each other. +- **SDL's macOS config also enables the X11 driver**, dynamically loaded from `/opt/X11`. + That would make `src/video/x11` a compile dependency on Apple for a driver nobody reaches + with Cocoa present; the generated header `#undef`s it. +- **`src/joystick/iphoneos` serves macOS too** — `SDL_JOYSTICK_MFI` is on in upstream's + macosx config and `SDL_gamecontroller.c` calls into it. +- **curl must be told which `strerror_r` it has** and refuses to build otherwise. Apple + ships the POSIX one; glibc's returns `char*`. +- **curl needs `secur32` on Windows** (`InitSecurityInterfaceA`, for the SSPI auth Schannel + builds on) and `CoreFoundation` + `SystemConfiguration` on macOS (proxy discovery). +- **The Linux SDL config's X11 had to be switched on by hand** — the CMake probe ran on a + host without system X11 development headers — and libudev switched off, since it is a + host library this index does not package. +- **`src/core/linux` is the one directory where a glob over-reaches**: `SDL_dbus.c` / + `SDL_ibus.c` / `SDL_fcitx.c` / `SDL_ime.c` are not internally guarded and simply fail + without dbus-1 headers. + +## Verification + +Cold, mcpp 0.0.109 (the `validate.yml` pin). All three platforms in CI, every member built +and run: + +| | linux | macos | windows | +|---|---|---|---| +| `compat.vulkan` | `loader api 1.4.357, WSI trampolines linked` | same | skipped (deferred) | +| `compat.curl` | `ssl=OpenSSL/3.5.1` | `ssl=OpenSSL/3.5.1` | `ssl=Schannel` | +| `compat.sdl2` | `driver=dummy, 320x240 window, events round-tripped` | same | same | + +### What the tests can and cannot assert + +- **SDL2 genuinely runs.** Its `dummy` video driver is a real driver, so the test executes + `SDL_Init`, `SDL_CreateWindow`, `SDL_GetWindowSize` and a full event round-trip. It is + the only one here that can be exercised rather than merely linked. +- **Vulkan is driverless by construction.** The loader advertises WSI *surface* extensions + only when an ICD supports them, so `VK_KHR_surface` is legitimately absent on a runner + with no GPU — an early draft asserted on it and failed, which is exactly the "testing the + runner's hardware" trap. Asserted instead: `vkEnumerateInstanceVersion` (answerable only + by the loader), `VK_EXT_debug_utils` (loader-implemented, driver-independent), and a + reference to `vkDestroySurfaceKHR` as link-time proof that `wsi.c` is in the library. +- **curl never opens a connection.** Asserted: init succeeds, `CURL_VERSION_SSL` with a + non-null `ssl_version` (a curl built without TLS still links and runs — it just cannot do + https), http+https in the protocol list, and that a handle accepts a real option set. + +## CN mirrors + +All five published to gitcode `mcpp-res`, byte-identical to GLOBAL, 200 on `curl`. SDL2's +GLOBAL is the `xlings-res/sdl2` repack described above rather than the upstream tag +archive. + +## Follow-up + +- `compat.vulkan` on Windows, if a supported static-loader path appears upstream. +- `compat.sdl2` currently has no Wayland backend; X11 only on Linux. diff --git a/README.md b/README.md index cb7d7e1..434a1f7 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,10 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上 | 原生模块库(Form A) | [`mcpplibs.xpkg`](pkgs/x/xpkg.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`tensorvia-cpu`](pkgs/t/tensorvia-cpu.lua) · [`ffmpeg`](pkgs/f/ffmpeg.lua)(模块层,源码经 `compat.ffmpeg` 直编) · [`opencv`](pkgs/o/opencv.lua)(单仓库:模块层与 OpenCV 5 全源码构建同在包内,索引侧只留本描述符) | | C 源码 compat(含 `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) | | header-only(含 `features`) | [`compat.eigen`](pkgs/c/compat.eigen.lua) | +| 运行时 loader compat(纯源码,绕开上游 codegen/asm) | [`compat.vulkan`](pkgs/c/compat.vulkan.lua)(Khronos loader:`loader/generated/` 已签入,汇编路径经 `UNKNOWN_FUNCTIONS_SUPPORTED` 降级为纯 C,故无需 CMake/Python/汇编器;windows 延后)· [`compat.vulkan-headers`](pkgs/c/compat.vulkan-headers.lua) | +| 全源码直编 + 生成 config(仅缺口平台) | [`compat.curl`](pkgs/c/compat.curl.lua)(win32 用上游签入 config,unix 生成) · [`compat.sdl2`](pkgs/c/compat.sdl2.lua)(win/mac 用上游签入 config,linux 生成 + 手工开 X11) | +| 补索引空缺的头文件包 | [`compat.glx-headers`](pkgs/c/compat.glx-headers.lua)(libglvnd 的 `GL/glx.h`,Khronos registry 不含,SDL 的 X11 后端必需) | +| 恒开的 interface define | [`compat.curl`](pkgs/c/compat.curl.lua) 的 `CURL_STATICLIB`:`cflags` 恒开但包私有,feature `defines` 可达消费端但需点名 —— `default = { implies = … }` 无条件生效,恰好两者兼得 | | 单包多 major(形态随版本切换) | [`compat.catch2`](pkgs/c/compat.catch2.lua)(3.x 编 `src/catch2/` 出静态库;2.x 走 `single_include/` header-only) | | 外部构建系统(`install()` 从源码构建) | [`compat.openblas`](pkgs/c/compat.openblas.lua)(Make) · [`compat.openssl`](pkgs/c/compat.openssl.lua)(Perl Configure + Make,静态 libssl/libcrypto) | | 全源码直编(config 快照 + 源列表,零外部构建系统) | [`compat.ffmpeg`](pkgs/c/compat.ffmpeg.lua)(2281 TU 含 NASM 汇编,28 个目录 glob 声明) | diff --git a/mcpp.toml b/mcpp.toml index 3372056..ad89ee5 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -17,6 +17,7 @@ members = [ "tests/examples/catch2-v2-main", "tests/examples/cjson", "tests/examples/core", + "tests/examples/curl", "tests/examples/eigen", "tests/examples/ffmpeg", "tests/examples/ffmpeg-module", @@ -32,6 +33,7 @@ members = [ "tests/examples/opencv-module", "tests/examples/opencv-module-dnn", "tests/examples/opencv-module-unifont", + "tests/examples/sdl2", "tests/examples/spdlog", "tests/examples/freetype", "tests/examples/glad", @@ -39,6 +41,7 @@ members = [ "tests/examples/md4c", "tests/examples/spdlog-compiled", "tests/examples/tinyhttps", + "tests/examples/vulkan", "tests/examples/tray", "tests/examples/yyjson", ] diff --git a/pkgs/c/compat.curl.lua b/pkgs/c/compat.curl.lua new file mode 100644 index 0000000..1b818cf --- /dev/null +++ b/pkgs/c/compat.curl.lua @@ -0,0 +1,330 @@ +-- compat.curl — libcurl 8.21.0, built from source as a static library. +-- +-- Full-source direct build (the `compat.ffmpeg` shape), not an install() hook +-- around autotools/CMake. What makes that practical here is curl's own +-- convention that every unused protocol and TLS backend compiles to an EMPTY +-- translation unit: `vtls/gtls.c` is `#ifdef USE_GNUTLS` from top to bottom, +-- `vquic/*.c` needs USE_HTTP3, `vssh/*.c` needs libssh. So the source list is +-- plain globs over lib/ and its subdirectories, and the configuration is +-- carried entirely by defines. Only `lib/dllmain.c` is excluded — it is the +-- DLL entry point, meaningless in a static build. +-- +-- THE CONFIG HEADER is the part upstream normally generates. curl_setup.h +-- picks it up as `#include "curl_config.h"` under HAVE_CONFIG_H, and ships +-- ready-made variants for some platforms but not for unix: +-- +-- * windows — `lib/config-win32.h` is checked in and curl_setup.h selects it +-- automatically when HAVE_CONFIG_H is absent. So Windows gets NO generated +-- config; it just must not define HAVE_CONFIG_H. +-- * linux / macosx — nothing checked in. The `mcpp_generated/curl_config.h` +-- below was produced by running curl's CMake configure against this +-- index's own gcc toolchain, then reduced to the entries that matter and +-- branched on `__linux__` / `__APPLE__`. Anything omitted merely costs curl +-- a fallback path, never correctness — which is why the Apple branch is +-- deliberately the conservative subset. +-- +-- Generating that config against the RIGHT compiler turned out to matter: a +-- first pass using the host `cc` produced a config claiming `ssize_t` did not +-- exist (its probe failed for an unrelated sysroot reason), and curl then +-- failed to compile against its own config. +-- +-- TLS: OpenSSL on linux/macosx through this index's `compat.openssl`; Schannel +-- on Windows, which is built into the OS — `compat.openssl` has no Windows +-- build, and Schannel is what upstream uses there anyway. +-- +-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*/` absorbs +-- the GitHub tarball's `curl-curl-8_21_0/` wrap layer. +package = { + spec = "1", + namespace = "compat", + name = "curl", + description = "libcurl — client-side URL transfer library (static, OpenSSL/Schannel TLS)", + licenses = {"curl"}, + repo = "https://github.com/curl/curl", + type = "package", + + xpm = { + linux = { + ["8.21.0"] = { + url = { + GLOBAL = "https://github.com/curl/curl/archive/refs/tags/curl-8_21_0.tar.gz", + CN = "https://gitcode.com/mcpp-res/curl/releases/download/8.21.0/curl-8.21.0.tar.gz", + }, + sha256 = "ec753aa6f408a3ca9f0d6d5f7a77417aecd1544db13c03ae5d443612bf367364", + }, + }, + macosx = { + ["8.21.0"] = { + url = { + GLOBAL = "https://github.com/curl/curl/archive/refs/tags/curl-8_21_0.tar.gz", + CN = "https://gitcode.com/mcpp-res/curl/releases/download/8.21.0/curl-8.21.0.tar.gz", + }, + sha256 = "ec753aa6f408a3ca9f0d6d5f7a77417aecd1544db13c03ae5d443612bf367364", + }, + }, + windows = { + ["8.21.0"] = { + url = { + GLOBAL = "https://github.com/curl/curl/archive/refs/tags/curl-8_21_0.tar.gz", + CN = "https://gitcode.com/mcpp-res/curl/releases/download/8.21.0/curl-8.21.0.tar.gz", + }, + sha256 = "ec753aa6f408a3ca9f0d6d5f7a77417aecd1544db13c03ae5d443612bf367364", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + + include_dirs = { "*/include", "*/lib", "mcpp_generated" }, + + sources = { + "*/lib/*.c", + "!*/lib/dllmain.c", -- DLL entry point; nothing to do in a static lib + "*/lib/curlx/*.c", + "*/lib/vauth/*.c", + "*/lib/vquic/*.c", -- empty TUs without USE_HTTP3 + "*/lib/vssh/*.c", -- empty TUs without libssh + "*/lib/vtls/*.c", -- one backend compiles, the rest are empty TUs + }, + + targets = { ["curl"] = { kind = "lib" } }, + deps = {}, + + -- decorates its declarations with __declspec(dllimport) + -- unless CURL_STATICLIB is defined, so a consumer that does not define + -- it links against import stubs that do not exist. It therefore has to + -- be an ALWAYS-ON, CONSUMER-VISIBLE define — and mcpp has no single key + -- for that: `cflags` is always on but package-private, while a feature's + -- `defines` reach the consumer but need naming. + -- + -- `default = { implies = ... }` is the combination that gives both. A + -- default feature's own `defines` are inert, but what it IMPLIES is + -- applied unconditionally — including when the consumer names some + -- other feature. Verified on 0.0.109 and on 2026.7.29.1; see + -- .agents/docs/2026-07-29-add-gui-backend-packages-plan.md. That quirk + -- makes `default` useless for expressing a mutually exclusive choice — + -- but here "unconditionally on" is exactly what is wanted. + features = { + ["default"] = { implies = { "staticlib" } }, + ["staticlib"] = { defines = { "CURL_STATICLIB" } }, + }, + + cflags = { + "-DBUILDING_LIBCURL", + "-DCURL_STATICLIB", + -- LDAP needs a system client library on every platform and no + -- consumer in this index speaks it. + "-DCURL_DISABLE_LDAP", + "-DCURL_DISABLE_LDAPS", + }, + + generated_files = { + ["mcpp_generated/curl_config.h"] = [==[ +/* curl_config.h — generated for mcpp-index from curl's CMake configure output. + * + * Windows never reaches this file: curl_setup.h selects the checked-in + * lib/config-win32.h when HAVE_CONFIG_H is undefined, and the Windows profile + * in the descriptor deliberately leaves it undefined. + * + * The common block is plain POSIX and holds on both linux and macOS. The + * per-platform blocks below carry only what genuinely differs. */ +#pragma once + +#define STDC_HEADERS 1 +#define _FILE_OFFSET_BITS 64 +#define CURL_EXTERN_SYMBOL __attribute__((__visibility__("default"))) + +/* sizes — both supported platforms are LP64 */ +#define SIZEOF_INT 4 +#define SIZEOF_LONG 8 +#define SIZEOF_OFF_T 8 +#define SIZEOF_SIZE_T 8 +#define SIZEOF_TIME_T 8 +#define SIZEOF_CURL_OFF_T 8 +#define SIZEOF_CURL_SOCKET_T 4 + +/* headers */ +#define HAVE_ARPA_INET_H 1 +#define HAVE_DIRENT_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_IFADDRS_H 1 +#define HAVE_LIBGEN_H 1 +#define HAVE_LOCALE_H 1 +#define HAVE_NETDB_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NETINET_TCP_H 1 +#define HAVE_NETINET_UDP_H 1 +#define HAVE_NET_IF_H 1 +#define HAVE_POLL_H 1 +#define HAVE_PWD_H 1 +#define HAVE_STDATOMIC_H 1 +#define HAVE_STDBOOL_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_POLL_H 1 +#define HAVE_SYS_RESOURCE_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_UN_H 1 +#define HAVE_TERMIOS_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UTIME_H 1 + +/* types */ +#define HAVE_ATOMIC 1 +#define HAVE_BOOL_T 1 +#define HAVE_SA_FAMILY_T 1 +#define HAVE_SUSECONDS_T 1 +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +#define HAVE_STRUCT_TIMEVAL 1 +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* functions */ +#define HAVE_ALARM 1 +#define HAVE_BASENAME 1 +#define HAVE_CLOCK_GETTIME_MONOTONIC 1 +#define HAVE_DECL_FSEEKO 1 +#define HAVE_FCNTL 1 +#define HAVE_FCNTL_O_NONBLOCK 1 +#define HAVE_FNMATCH 1 +#define HAVE_FREEADDRINFO 1 +#define HAVE_FSEEKO 1 +#define HAVE_GETADDRINFO 1 +#define HAVE_GETADDRINFO_THREADSAFE 1 +#define HAVE_GETEUID 1 +#define HAVE_GETHOSTNAME 1 +#define HAVE_GETIFADDRS 1 +#define HAVE_GETPEERNAME 1 +#define HAVE_GETPPID 1 +#define HAVE_GETPWUID 1 +#define HAVE_GETPWUID_R 1 +#define HAVE_GETRLIMIT 1 +#define HAVE_GETSOCKNAME 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GMTIME_R 1 +#define HAVE_IF_NAMETOINDEX 1 +#define HAVE_INET_NTOP 1 +#define HAVE_INET_PTON 1 +#define HAVE_IOCTL_FIONBIO 1 +#define HAVE_IOCTL_SIOCGIFADDR 1 +#define HAVE_LOCALTIME_R 1 +#define HAVE_OPENDIR 1 +#define HAVE_PIPE 1 +#define HAVE_POLL 1 +#define HAVE_REALPATH 1 +#define HAVE_RECV 1 +#define HAVE_SCHED_YIELD 1 +#define HAVE_SELECT 1 +#define HAVE_SEND 1 +#define HAVE_SENDMSG 1 +#define HAVE_SETLOCALE 1 +#define HAVE_SETRLIMIT 1 +#define HAVE_SIGACTION 1 +#define HAVE_SIGINTERRUPT 1 +#define HAVE_SIGNAL 1 +#define HAVE_SIGSETJMP 1 +#define HAVE_SOCKET 1 +#define HAVE_SOCKETPAIR 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRERROR_R 1 +#define HAVE_THREADS_POSIX 1 +#define HAVE_UTIME 1 +#define HAVE_UTIMES 1 +#define HAVE_WRITABLE_ARGV 1 + +/* TLS + resolver */ +#define USE_OPENSSL 1 +#define USE_TLS_SRP 1 +#define HAVE_OPENSSL_SRP 1 +#define HAVE_SSL_SET0_WBIO 1 +#define HAVE_DES_ECB_ENCRYPT 1 +#define USE_IPV6 1 +#define USE_RESOLV_THREADED 1 + +#if defined(__linux__) + +#define CURL_OS "Linux" +/* glibc's strerror_r returns char*, not int — curl needs to know which */ +#define HAVE_GLIBC_STRERROR_R 1 +#define HAVE_GETHOSTBYNAME_R 1 +#define HAVE_GETHOSTBYNAME_R_6 1 +#define HAVE_ACCEPT4 1 +#define HAVE_PIPE2 1 +#define HAVE_EVENTFD 1 +#define HAVE_SYS_EVENTFD_H 1 +#define HAVE_SENDMMSG 1 +#define HAVE_MEMRCHR 1 +#define HAVE_FSETXATTR 1 +#define HAVE_FSETXATTR_5 1 +#define HAVE_LINUX_TCP_H 1 +#define HAVE_TERMIO_H 1 +#define HAVE_CLOCK_GETTIME_MONOTONIC_RAW 1 +/* Debian/Fedora layout; overridable at runtime with CURLOPT_CAINFO or the + * SSL_CERT_FILE environment variable. */ +#define CURL_CA_BUNDLE "/etc/ssl/certs/ca-certificates.crt" +#define CURL_CA_PATH "/etc/ssl/certs" + +#elif defined(__APPLE__) + +#define CURL_OS "Darwin" +/* Conservative on purpose — every Linux-only entry above is simply omitted + * rather than guessed at, which costs curl a fallback path at worst. + * fsetxattr takes six arguments here, not five. */ +#define HAVE_FSETXATTR 1 +#define HAVE_FSETXATTR_6 1 +#define HAVE_MACH_ABSOLUTE_TIME 1 +/* curl requires knowing WHICH strerror_r it has and refuses to build otherwise + * ("strerror_r MUST be either POSIX, glibc style"). Apple ships the POSIX one + * that returns int; glibc's returns char*, which is the linux branch above. */ +#define HAVE_POSIX_STRERROR_R 1 +/* macOS ships no /etc/ssl/certs directory; LibreSSL's bundle is the one file + * that is reliably present. An OpenSSL-backed curl needs SOME bundle. */ +#define CURL_CA_BUNDLE "/etc/ssl/cert.pem" + +#else +#error "compat.curl: no curl_config.h branch for this platform" +#endif +]==], + }, + + -- ── Platform-specific ────────────────────────────────────────────── + + linux = { + cflags = { "-DHAVE_CONFIG_H", "-D_GNU_SOURCE" }, + deps = { ["compat.openssl"] = "3.5.1" }, + ldflags = { "-lpthread" }, + }, + + macosx = { + cflags = { "-DHAVE_CONFIG_H", "-D_GNU_SOURCE" }, + deps = { ["compat.openssl"] = "3.5.1" }, + -- curl reaches into the system for proxy configuration on Apple: + -- SystemConfiguration for SCDynamicStoreCopyProxies, and + -- CoreFoundation for the CF objects that hands back. + ldflags = { + "-lpthread", + "-framework", "CoreFoundation", + "-framework", "SystemConfiguration", + }, + }, + + windows = { + -- No HAVE_CONFIG_H on purpose: that is what makes curl_setup.h + -- reach for the checked-in lib/config-win32.h. + -- Schannel is the OS TLS stack; USE_WINDOWS_SSPI is what turns on + -- the SSPI-based auth code paths it needs. + cflags = { "-DUSE_SCHANNEL", "-DUSE_WINDOWS_SSPI" }, + ldflags = { + "-lws2_32", "-lcrypt32", "-lbcrypt", + "-ladvapi32", "-lnormaliz", + -- secur32 carries InitSecurityInterfaceA, which curl_sspi.c + -- needs for the SSPI auth Schannel builds on. + "-lsecur32", + }, + }, + }, +} diff --git a/pkgs/c/compat.glx-headers.lua b/pkgs/c/compat.glx-headers.lua new file mode 100644 index 0000000..b8923cb --- /dev/null +++ b/pkgs/c/compat.glx-headers.lua @@ -0,0 +1,80 @@ +-- compat.glx-headers — GL and GLX API headers, from libglvnd. +-- +-- Fills a real hole: `GL/glx.h` is NOT part of the Khronos OpenGL-Registry, so +-- `compat.opengl` cannot supply it (that package's `*/api` carries glcorearb.h, +-- glext.h, glxext.h, wgl.h — no glx.h). On Linux the canonical provider is +-- libglvnd, which is also the package the GL runtime plan already names as the +-- wanted dispatch provider (.agents/docs/2026-06-03-gl-runtime-packages-plan.md). +-- Only its headers are taken here; the dispatch libraries remain out of scope, +-- and `compat.glx-runtime` continues to own the runtime side. +-- +-- `compat.sdl2` needs this: SDL's X11 video driver includes from +-- SDL_x11opengl.h whenever SDL_VIDEO_OPENGL_GLX is on, and without it the whole +-- X11 backend fails to compile. (compat.glfw does not, because GLFW vendors its +-- own minimal GLX declarations in src/glx_context.h.) +-- +-- Header-only, the `compat.opengl` shape: one include root plus an anchor TU so +-- the package still produces a buildable lib target. +-- +-- NOTE ON OVERLAP: this include root also carries `GL/gl.h`, `GL/glcorearb.h` +-- and `GL/glext.h`, which `compat.opengl` provides too. Depend on ONE of the +-- two, not both, or the winner depends on include-dir order. Consumers wanting +-- GLX should take this package; consumers wanting only core GL should keep +-- taking `compat.opengl`. +package = { + spec = "1", + namespace = "compat", + name = "glx-headers", + description = "GL and GLX API headers (libglvnd) — provides GL/glx.h", + licenses = {"MIT"}, + repo = "https://github.com/NVIDIA/libglvnd", + type = "package", + + xpm = { + linux = { + ["1.7.0"] = { + url = { + GLOBAL = "https://github.com/NVIDIA/libglvnd/archive/refs/tags/v1.7.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/glx-headers/releases/download/1.7.0/glx-headers-1.7.0.tar.gz", + }, + sha256 = "073e7292788d4d3eeb45ea6c7bdcce9bfdb3b3eef8d7dbd47f2f30dce046ef98", + }, + }, + macosx = { + ["1.7.0"] = { + url = { + GLOBAL = "https://github.com/NVIDIA/libglvnd/archive/refs/tags/v1.7.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/glx-headers/releases/download/1.7.0/glx-headers-1.7.0.tar.gz", + }, + sha256 = "073e7292788d4d3eeb45ea6c7bdcce9bfdb3b3eef8d7dbd47f2f30dce046ef98", + }, + }, + windows = { + ["1.7.0"] = { + url = { + GLOBAL = "https://github.com/NVIDIA/libglvnd/archive/refs/tags/v1.7.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/glx-headers/releases/download/1.7.0/glx-headers-1.7.0.tar.gz", + }, + sha256 = "073e7292788d4d3eeb45ea6c7bdcce9bfdb3b3eef8d7dbd47f2f30dce046ef98", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + include_dirs = { "*/include" }, + generated_files = { + ["mcpp_generated/glx_headers_anchor.c"] = + "int mcpp_compat_glx_headers_anchor(void) { return 0; }\n", + }, + sources = { "mcpp_generated/glx_headers_anchor.c" }, + targets = { ["glx-headers"] = { kind = "lib" } }, + -- GL/glx.h includes and . + deps = { + ["compat.x11"] = "1.8.13", + ["compat.xorgproto"] = "2025.1", + }, + }, +} diff --git a/pkgs/c/compat.sdl2.lua b/pkgs/c/compat.sdl2.lua new file mode 100644 index 0000000..3b76806 --- /dev/null +++ b/pkgs/c/compat.sdl2.lua @@ -0,0 +1,923 @@ +-- compat.sdl2 — SDL 2.32.10, built from source as a static library. +-- +-- Cross-platform window, input and audio layer. Full-source direct build, the +-- `compat.ffmpeg` / +-- `compat.curl` shape: SDL guards every backend it did not select +-- (`src/video/windows/*.c` opens with `#if SDL_VIDEO_DRIVER_WINDOWS`, the +-- direct3d/psp/ps2 renderers likewise), so unselected files compile to EMPTY +-- translation units and the source list can be plain directory globs with the +-- configuration carried entirely by SDL_config.h. +-- +-- THE CONFIG HEADER is the only genuinely awkward part, and it is awkward on +-- exactly one platform: +-- +-- * windows / macosx — upstream CHECKS IN `include/SDL_config_windows.h` and +-- `include/SDL_config_macosx.h`, and `include/SDL_config.h` is a dispatcher +-- to them. Nothing to generate. +-- * linux — upstream's dispatcher falls through to `SDL_config_minimal.h`, +-- which builds an SDL that can do essentially nothing. This is the gap the +-- generated header below fills. +-- +-- So `mcpp_generated/SDL_config.h` shadows upstream's dispatcher and +-- reproduces it for windows/macosx, while carrying CMake's generated Linux +-- configuration inline. X11 is switched on by hand at the end of that block: +-- the CMake probe ran on a host without system X11 development headers and +-- disabled it, but this index supplies X11 through the same packages +-- `compat.glfw` links. +-- +-- SOURCE IS A REPACK, not the upstream tag archive. SDL's GitHub archive carries +-- two POSIX symlinks under `android-project-ant/`, and a tag archive containing +-- symlinks fails to extract on Windows — the package then "installs" with +-- nothing in it, publishes no include dirs, and every consumer fails with +-- `'SDL.h' file not found` while the package itself reports success. That is +-- exactly what CI showed before this change. `chriskohlhoff.asio` hit the same +-- wall and set the precedent: host a symlink-free repack on xlings-res +-- (GLOBAL) and mirror the identical bytes to mcpp-res (CN). Only the two +-- symlink entries are removed; everything else is the upstream content. +-- +-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*/` absorbs +-- the tarball's `SDL-release-2.32.10/` wrap layer. +package = { + spec = "1", + namespace = "compat", + name = "sdl2", + description = "SDL2 — cross-platform window, input and audio layer", + licenses = {"Zlib"}, + repo = "https://github.com/libsdl-org/SDL", + type = "package", + + xpm = { + linux = { + ["2.32.10"] = { + url = { + GLOBAL = "https://github.com/xlings-res/sdl2/releases/download/2.32.10/sdl2-2.32.10-nosymlinks.tar.gz", + CN = "https://gitcode.com/mcpp-res/sdl2/releases/download/2.32.10-nosymlinks/sdl2-2.32.10-nosymlinks.tar.gz", + }, + sha256 = "8823b81a7ecec5c1785dfd3c1fdb6260899d4eaa07574365dd4b8da9e2830385", + }, + }, + macosx = { + ["2.32.10"] = { + url = { + GLOBAL = "https://github.com/xlings-res/sdl2/releases/download/2.32.10/sdl2-2.32.10-nosymlinks.tar.gz", + CN = "https://gitcode.com/mcpp-res/sdl2/releases/download/2.32.10-nosymlinks/sdl2-2.32.10-nosymlinks.tar.gz", + }, + sha256 = "8823b81a7ecec5c1785dfd3c1fdb6260899d4eaa07574365dd4b8da9e2830385", + }, + }, + windows = { + ["2.32.10"] = { + url = { + GLOBAL = "https://github.com/xlings-res/sdl2/releases/download/2.32.10/sdl2-2.32.10-nosymlinks.tar.gz", + CN = "https://gitcode.com/mcpp-res/sdl2/releases/download/2.32.10-nosymlinks/sdl2-2.32.10-nosymlinks.tar.gz", + }, + sha256 = "8823b81a7ecec5c1785dfd3c1fdb6260899d4eaa07574365dd4b8da9e2830385", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c99", + + -- mcpp_generated FIRST so our SDL_config.h shadows upstream's + -- dispatcher; */include carries the public SDL headers and the + -- per-platform configs our header defers to. + -- */src/video/khronos carries SDL's vendored EGL and GLES headers, + -- which SDL_VIDEO_OPENGL_EGL / _ES2 reach for. + include_dirs = { "mcpp_generated", "*/include", "*/src", "*/src/video/khronos" }, + + -- Backend-independent core plus every backend directory. SDL's own + -- guards decide what survives the preprocessor, which is what lets one + -- list serve all three platforms. + sources = { + "*/src/*.c", + "*/src/atomic/*.c", + "*/src/audio/*.c", + "*/src/audio/disk/*.c", + "*/src/audio/dummy/*.c", + "*/src/cpuinfo/*.c", + "*/src/dynapi/*.c", + "*/src/events/*.c", + "*/src/file/*.c", + "*/src/haptic/*.c", + -- Only the top level: SDL_hidapi.c is SDL's own wrapper and is + -- always needed (SDL_hid_* is public API). The subdirectories under + -- it are the vendored hidapi backends, which SDL_HIDAPI gates and + -- which this build does not use. + "*/src/hidapi/*.c", + "*/src/joystick/*.c", + -- SDL_JOYSTICK_HIDAPI is off in the generated Linux config but ON in + -- upstream's checked-in macosx/windows ones, and SDL_gamecontroller.c + -- calls into it unconditionally there + -- (HIDAPI_GetGameControllerTypeFromGUID). Guarded internally, so it + -- costs nothing where the config disables it. + "*/src/joystick/hidapi/*.c", + "*/src/joystick/steam/*.c", + "*/src/joystick/virtual/*.c", + "*/src/libm/*.c", + "*/src/locale/*.c", + "*/src/misc/*.c", + "*/src/power/*.c", + "*/src/render/*.c", + "*/src/render/direct3d/*.c", + "*/src/render/direct3d11/*.c", + "*/src/render/direct3d12/*.c", + "*/src/render/opengl/*.c", + "*/src/render/opengles/*.c", + "*/src/render/opengles2/*.c", + "*/src/render/ps2/*.c", + "*/src/render/psp/*.c", + "*/src/render/software/*.c", + "*/src/render/vitagxm/*.c", + "*/src/sensor/*.c", + "*/src/sensor/dummy/*.c", + "*/src/stdlib/*.c", + "*/src/thread/*.c", + "*/src/timer/*.c", + "*/src/video/*.c", + "*/src/video/dummy/*.c", + "*/src/video/offscreen/*.c", + "*/src/video/yuv2rgb/*.c", + }, + + targets = { ["sdl2"] = { kind = "lib" } }, + deps = {}, + + generated_files = { + ["mcpp_generated/SDL_config.h"] = [==[ +/* SDL_config.h — supplied by mcpp-index. + * + * Only LINUX needs this. Upstream ships ready-made configs for the other two + * platforms (include/SDL_config_windows.h, include/SDL_config_macosx.h) and its + * own include/SDL_config.h is just a dispatcher to them; the branches below + * reproduce that dispatch. Linux is the gap — upstream's dispatcher falls + * through to SDL_config_minimal.h there, which builds an SDL that can do + * essentially nothing. + * + * The Linux body is CMake's generated output against this index's gcc + * toolchain, verbatim, plus the X11 block at the end. */ +#ifndef SDL_config_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#if defined(__WIN32__) +/* SDL_config_windows.h only turns HAVE_LIBC on for _MSC_VER, and this index + * builds with clang++ rather than clang-cl. Left off, SDL compiles its own + * memcpy/memset in src/stdlib/SDL_mslibc.c and the link fails with + * "memcpy already defined in SDL_mslibc.o" against libvcruntime. */ +#define HAVE_LIBC 1 +#include "SDL_config_windows.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +/* Upstream's macOS config also enables the X11 video driver, dynamically loaded + * from /opt/X11. That would make src/video/x11 a compile dependency on Apple — + * X11 headers and all — for a driver nobody reaches on a Mac with Cocoa + * present. Turned off here; Cocoa and the dummy driver remain. */ +#undef SDL_VIDEO_DRIVER_X11 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +#undef SDL_VIDEO_DRIVER_X11_XDBE +#undef SDL_VIDEO_DRIVER_X11_XRANDR +#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#undef SDL_VIDEO_DRIVER_X11_XSHAPE +#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#undef SDL_VIDEO_DRIVER_X11_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +#elif defined(__linux__) + + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C language features */ +/* #undef const */ +/* #undef inline */ +/* #undef volatile */ + +/* C datatypes */ +/* Define SIZEOF_VOIDP for 64/32 architectures */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define HAVE_GCC_ATOMICS 1 +/* #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET */ + +/* Comment this if you want to build without any C library requirements */ +#define HAVE_LIBC 1 +#ifdef HAVE_LIBC + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_WCHAR_H 1 +#define HAVE_LINUX_INPUT_H 1 +/* #undef HAVE_PTHREAD_NP_H */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#endif +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +/* #undef HAVE__WCSDUP */ +#define HAVE_WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_WCSCASECMP 1 +/* #undef HAVE__WCSICMP */ +#define HAVE_WCSNCASECMP 1 +/* #undef HAVE__WCSNICMP */ +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +/* #undef HAVE__STRREV */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_INDEX 1 +#define HAVE_RINDEX 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__UITOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE__I64TOA */ +/* #undef HAVE__UI64TOA */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +/* #undef HAVE__STRICMP */ +#define HAVE_STRCASECMP 1 +/* #undef HAVE__STRNICMP */ +#define HAVE_STRNCASECMP 1 +#define HAVE_STRCASESTR 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_FOPEN64 1 +#define HAVE_FSEEKO 1 +#define HAVE_FSEEKO64 1 +#define HAVE_MEMFD_CREATE 1 +#define HAVE_POSIX_FALLOCATE 1 +#define HAVE_SIGACTION 1 +#define HAVE_SIGTIMEDWAIT 1 +#define HAVE_SA_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +/* #undef HAVE_SYSCTLBYNAME */ +#define HAVE_CLOCK_GETTIME 1 +/* #undef HAVE_GETPAGESIZE */ +#define HAVE_MPROTECT 1 +#define HAVE_ICONV 1 +/* #undef SDL_USE_LIBICONV */ +#define HAVE_PTHREAD_SETNAME_NP 1 +/* #undef HAVE_PTHREAD_SET_NAME_NP */ +#define HAVE_SEM_TIMEDWAIT 1 +#define HAVE_GETAUXVAL 1 +/* #undef HAVE_ELF_AUX_INFO */ +#define HAVE_POLL 1 +#define HAVE__EXIT 1 + +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_FLOAT_H 1 +#endif /* HAVE_LIBC */ + +/* #undef HAVE_ALTIVEC_H */ +/* #undef HAVE_DBUS_DBUS_H */ +/* #undef HAVE_FCITX */ +/* #undef HAVE_IBUS_IBUS_H */ +#define HAVE_SYS_INOTIFY_H 1 +#define HAVE_INOTIFY_INIT 1 +#define HAVE_INOTIFY_INIT1 1 +#define HAVE_INOTIFY 1 +/* #undef HAVE_LIBUSB */ +#define HAVE_O_CLOEXEC 1 + +/* Apple platforms might be building universal binaries, where Intel builds + can use immintrin.h but other architectures can't. */ +#ifdef __APPLE__ +# if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +# endif +#else /* non-Apple platforms can use the normal CMake check for this. */ +#define HAVE_IMMINTRIN_H 1 +#endif + +/* libudev is deliberately OFF: it is a host system library this index does not + * package, and SDL only uses it to enumerate input devices. Without it SDL + * falls back to scanning /dev/input directly, which is the same path it takes + * on any udev-less system. Leaving the CMake probe's value in would make + * src/joystick/linux and src/haptic/linux fail on . */ +/* #undef HAVE_LIBUDEV_H */ +/* #undef HAVE_LIBSAMPLERATE_H */ +/* #undef HAVE_LIBDECOR_H */ + +/* #undef HAVE_D3D_H */ +/* #undef HAVE_D3D11_H */ +/* #undef HAVE_D3D12_H */ +/* #undef HAVE_DDRAW_H */ +/* #undef HAVE_DSOUND_H */ +/* #undef HAVE_DINPUT_H */ +/* #undef HAVE_XINPUT_H */ +/* #undef HAVE_WINDOWS_GAMING_INPUT_H */ +/* #undef HAVE_DXGI_H */ + +/* #undef HAVE_MMDEVICEAPI_H */ +/* #undef HAVE_AUDIOCLIENT_H */ +/* #undef HAVE_TPCSHRD_H */ +/* #undef HAVE_SENSORSAPI_H */ +/* #undef HAVE_ROAPI_H */ +/* #undef HAVE_SHELLSCALINGAPI_H */ + +/* #undef USE_POSIX_SPAWN */ + +/* SDL internal assertion support */ +#if 0 +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ +#endif + +/* Allow disabling of core subsystems */ +/* #undef SDL_ATOMIC_DISABLED */ +/* #undef SDL_AUDIO_DISABLED */ +/* #undef SDL_CPUINFO_DISABLED */ +/* #undef SDL_EVENTS_DISABLED */ +/* #undef SDL_FILE_DISABLED */ +/* #undef SDL_JOYSTICK_DISABLED */ +/* #undef SDL_HAPTIC_DISABLED */ +#define SDL_HIDAPI_DISABLED 1 +/* #undef SDL_SENSOR_DISABLED */ +/* #undef SDL_LOADSO_DISABLED */ +/* #undef SDL_RENDER_DISABLED */ +/* #undef SDL_THREADS_DISABLED */ +/* #undef SDL_TIMERS_DISABLED */ +/* #undef SDL_VIDEO_DISABLED */ +/* #undef SDL_POWER_DISABLED */ +/* #undef SDL_FILESYSTEM_DISABLED */ +/* #undef SDL_LOCALE_DISABLED */ +/* #undef SDL_MISC_DISABLED */ + +/* Enable various audio drivers */ +/* #undef SDL_AUDIO_DRIVER_ALSA */ +/* #undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_ANDROID */ +/* #undef SDL_AUDIO_DRIVER_OPENSLES */ +/* #undef SDL_AUDIO_DRIVER_AAUDIO */ +/* #undef SDL_AUDIO_DRIVER_ARTS */ +/* #undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_COREAUDIO */ +#define SDL_AUDIO_DRIVER_DISK 1 +/* #undef SDL_AUDIO_DRIVER_DSOUND */ +#define SDL_AUDIO_DRIVER_DUMMY 1 +/* #undef SDL_AUDIO_DRIVER_EMSCRIPTEN */ +/* #undef SDL_AUDIO_DRIVER_ESD */ +/* #undef SDL_AUDIO_DRIVER_ESD_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_HAIKU */ +/* #undef SDL_AUDIO_DRIVER_JACK */ +/* #undef SDL_AUDIO_DRIVER_JACK_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_NAS */ +/* #undef SDL_AUDIO_DRIVER_NAS_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_NETBSD */ +/* #undef SDL_AUDIO_DRIVER_OSS */ +/* #undef SDL_AUDIO_DRIVER_PAUDIO */ +/* #undef SDL_AUDIO_DRIVER_PIPEWIRE */ +/* #undef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_PULSEAUDIO */ +/* #undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_QSA */ +/* #undef SDL_AUDIO_DRIVER_SNDIO */ +/* #undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_SUNAUDIO */ +/* #undef SDL_AUDIO_DRIVER_WASAPI */ +/* #undef SDL_AUDIO_DRIVER_WINMM */ +/* #undef SDL_AUDIO_DRIVER_OS2 */ +/* #undef SDL_AUDIO_DRIVER_VITA */ +/* #undef SDL_AUDIO_DRIVER_PSP */ +/* #undef SDL_AUDIO_DRIVER_PS2 */ +/* #undef SDL_AUDIO_DRIVER_N3DS */ + +/* Enable various input drivers */ +#define SDL_INPUT_LINUXEV 1 +#define SDL_INPUT_LINUXKD 1 +/* #undef SDL_INPUT_FBSDKBIO */ +/* #undef SDL_INPUT_WSCONS */ +/* #undef SDL_JOYSTICK_ANDROID */ +/* #undef SDL_JOYSTICK_HAIKU */ +/* #undef SDL_JOYSTICK_WGI */ +/* #undef SDL_JOYSTICK_DINPUT */ +/* #undef SDL_JOYSTICK_XINPUT */ +/* #undef SDL_JOYSTICK_DUMMY */ +/* #undef SDL_JOYSTICK_IOKIT */ +/* #undef SDL_JOYSTICK_MFI */ +#define SDL_JOYSTICK_LINUX 1 +/* #undef SDL_JOYSTICK_OS2 */ +/* #undef SDL_JOYSTICK_USBHID */ +/* #undef SDL_HAVE_MACHINE_JOYSTICK_H */ +/* #undef SDL_JOYSTICK_HIDAPI */ +/* #undef SDL_JOYSTICK_RAWINPUT */ +/* #undef SDL_JOYSTICK_EMSCRIPTEN */ +/* #undef SDL_JOYSTICK_VIRTUAL */ +/* #undef SDL_JOYSTICK_VITA */ +/* #undef SDL_JOYSTICK_PSP */ +/* #undef SDL_JOYSTICK_PS2 */ +/* #undef SDL_JOYSTICK_N3DS */ +/* #undef SDL_HAPTIC_DUMMY */ +#define SDL_HAPTIC_LINUX 1 +/* #undef SDL_HAPTIC_IOKIT */ +/* #undef SDL_HAPTIC_DINPUT */ +/* #undef SDL_HAPTIC_XINPUT */ +/* #undef SDL_HAPTIC_ANDROID */ +/* #undef SDL_LIBUSB_DYNAMIC */ +/* #undef SDL_UDEV_DYNAMIC */ + +/* Enable various sensor drivers */ +/* #undef SDL_SENSOR_ANDROID */ +/* #undef SDL_SENSOR_COREMOTION */ +/* #undef SDL_SENSOR_WINDOWS */ +#define SDL_SENSOR_DUMMY 1 +/* #undef SDL_SENSOR_VITA */ +/* #undef SDL_SENSOR_N3DS */ + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 +/* #undef SDL_LOADSO_DUMMY */ +/* #undef SDL_LOADSO_LDG */ +/* #undef SDL_LOADSO_WINDOWS */ +/* #undef SDL_LOADSO_OS2 */ + +/* Enable various threading systems */ +/* #undef SDL_THREAD_GENERIC_COND_SUFFIX */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 +/* #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP */ +/* #undef SDL_THREAD_WINDOWS */ +/* #undef SDL_THREAD_OS2 */ +/* #undef SDL_THREAD_VITA */ +/* #undef SDL_THREAD_PSP */ +/* #undef SDL_THREAD_PS2 */ +/* #undef SDL_THREAD_N3DS */ + +/* Enable various timer systems */ +/* #undef SDL_TIMER_HAIKU */ +/* #undef SDL_TIMER_DUMMY */ +#define SDL_TIMER_UNIX 1 +/* #undef SDL_TIMER_WINDOWS */ +/* #undef SDL_TIMER_OS2 */ +/* #undef SDL_TIMER_VITA */ +/* #undef SDL_TIMER_PSP */ +/* #undef SDL_TIMER_PS2 */ +/* #undef SDL_TIMER_N3DS */ + +/* Enable various video drivers */ +/* #undef SDL_VIDEO_DRIVER_ANDROID */ +/* #undef SDL_VIDEO_DRIVER_EMSCRIPTEN */ +/* #undef SDL_VIDEO_DRIVER_HAIKU */ +/* #undef SDL_VIDEO_DRIVER_COCOA */ +/* #undef SDL_VIDEO_DRIVER_UIKIT */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_OFFSCREEN 1 +/* #undef SDL_VIDEO_DRIVER_WINDOWS */ +/* #undef SDL_VIDEO_DRIVER_WINRT */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND */ +/* #undef SDL_VIDEO_DRIVER_RPI */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE_VDK */ +/* #undef SDL_VIDEO_DRIVER_OS2 */ +/* #undef SDL_VIDEO_DRIVER_QNX */ +/* #undef SDL_VIDEO_DRIVER_RISCOS */ +/* #undef SDL_VIDEO_DRIVER_PSP */ +/* #undef SDL_VIDEO_DRIVER_PS2 */ + +/* #undef SDL_VIDEO_DRIVER_KMSDRM */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM */ + +/* #undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR */ + +/* #undef SDL_VIDEO_DRIVER_X11 */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS */ +/* #undef SDL_VIDEO_DRIVER_X11_XCURSOR */ +/* #undef SDL_VIDEO_DRIVER_X11_XDBE */ +/* #undef SDL_VIDEO_DRIVER_X11_XINPUT2 */ +/* #undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH */ +/* #undef SDL_VIDEO_DRIVER_X11_XFIXES */ +/* #undef SDL_VIDEO_DRIVER_X11_XRANDR */ +/* #undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER */ +/* #undef SDL_VIDEO_DRIVER_X11_XSHAPE */ +/* #undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */ +/* #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM */ +/* #undef SDL_VIDEO_DRIVER_VITA */ +/* #undef SDL_VIDEO_DRIVER_N3DS */ + +/* #undef SDL_VIDEO_RENDER_D3D */ +/* #undef SDL_VIDEO_RENDER_D3D11 */ +/* #undef SDL_VIDEO_RENDER_D3D12 */ +#define SDL_VIDEO_RENDER_OGL 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +/* #undef SDL_VIDEO_RENDER_DIRECTFB */ +/* #undef SDL_VIDEO_RENDER_METAL */ +/* #undef SDL_VIDEO_RENDER_VITA_GXM */ +/* #undef SDL_VIDEO_RENDER_PS2 */ +/* #undef SDL_VIDEO_RENDER_PSP */ + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +#define SDL_VIDEO_OPENGL_GLX 1 +/* #undef SDL_VIDEO_OPENGL_WGL */ +#define SDL_VIDEO_OPENGL_EGL 1 +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable Metal support */ +/* #undef SDL_VIDEO_METAL */ + +/* Enable system power support */ +/* #undef SDL_POWER_ANDROID */ +#define SDL_POWER_LINUX 1 +/* #undef SDL_POWER_WINDOWS */ +/* #undef SDL_POWER_WINRT */ +/* #undef SDL_POWER_MACOSX */ +/* #undef SDL_POWER_UIKIT */ +/* #undef SDL_POWER_HAIKU */ +/* #undef SDL_POWER_EMSCRIPTEN */ +/* #undef SDL_POWER_HARDWIRED */ +/* #undef SDL_POWER_VITA */ +/* #undef SDL_POWER_PSP */ +/* #undef SDL_POWER_N3DS */ + +/* Enable system filesystem support */ +/* #undef SDL_FILESYSTEM_ANDROID */ +/* #undef SDL_FILESYSTEM_HAIKU */ +/* #undef SDL_FILESYSTEM_COCOA */ +/* #undef SDL_FILESYSTEM_DUMMY */ +/* #undef SDL_FILESYSTEM_RISCOS */ +#define SDL_FILESYSTEM_UNIX 1 +/* #undef SDL_FILESYSTEM_WINDOWS */ +/* #undef SDL_FILESYSTEM_EMSCRIPTEN */ +/* #undef SDL_FILESYSTEM_OS2 */ +/* #undef SDL_FILESYSTEM_VITA */ +/* #undef SDL_FILESYSTEM_PSP */ +/* #undef SDL_FILESYSTEM_PS2 */ +/* #undef SDL_FILESYSTEM_N3DS */ + +/* Enable misc subsystem */ +/* #undef SDL_MISC_DUMMY */ + +/* Enable locale subsystem */ +/* #undef SDL_LOCALE_DUMMY */ + +/* Enable assembly routines */ +/* #undef SDL_ALTIVEC_BLITTERS */ +/* #undef SDL_ARM_SIMD_BLITTERS */ +/* #undef SDL_ARM_NEON_BLITTERS */ + +/* Whether SDL_DYNAMIC_API needs dlopen */ +#define DYNAPI_NEEDS_DLOPEN 1 + +/* Enable dynamic libsamplerate support */ +/* #undef SDL_LIBSAMPLERATE_DYNAMIC */ + +/* Enable ime support */ +/* #undef SDL_USE_IME */ + +/* Platform specific definitions */ +/* #undef SDL_IPHONE_KEYBOARD */ +/* #undef SDL_IPHONE_LAUNCHSCREEN */ + +/* #undef SDL_VIDEO_VITA_PIB */ +/* #undef SDL_VIDEO_VITA_PVR */ +/* #undef SDL_VIDEO_VITA_PVR_OGL */ + +/* #undef SDL_HAVE_LIBDECOR_GET_MIN_MAX */ + +#if !defined(HAVE_STDINT_H) && !defined(_STDINT_H_) +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +#endif /* Visual Studio 2008 */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ +/* ── X11 video, enabled for mcpp-index ─────────────────────────────────────── + * The CMake probe that produced this file ran on a host without system X11 + * development headers, so it disabled X11 and left only the dummy/offscreen + * drivers. This index does supply X11 — the same set compat.glfw links — so the + * driver is switched on here explicitly. + * + * NOT dynamic: SDL_VIDEO_DRIVER_X11_DYNAMIC would make SDL dlopen libX11.so at + * runtime, but compat.x11 is a static library, so the symbols must be linked. + * + * XSCRNSAVER is absent on purpose — the index has no compat.xscrnsaver. Its + * only effect is that SDL falls back to its own screensaver inhibition path. */ +#define SDL_VIDEO_DRIVER_X11 1 +#define SDL_VIDEO_DRIVER_X11_XCURSOR 1 +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#define SDL_VIDEO_DRIVER_X11_XFIXES 1 +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1 +#define SDL_VIDEO_DRIVER_X11_XRANDR 1 +#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 + +#else +#error "compat.sdl2: no SDL_config.h branch for this platform" +#endif + +#endif /* SDL_config_h_ */ +]==], + }, + + linux = { + sources = { + -- The ONE directory where a glob over-reaches: SDL_dbus.c, + -- SDL_ibus.c, SDL_fcitx.c and SDL_ime.c are the DBus-based IME + -- stack and are NOT guarded by an internal #if — they simply + -- fail to compile without dbus-1 headers, which this index does + -- not package. Upstream's CMake omits them under + -- -DSDL_DBUS=OFF; this list does the same. + "*/src/core/linux/SDL_evdev.c", + "*/src/core/linux/SDL_evdev_capabilities.c", + "*/src/core/linux/SDL_evdev_kbd.c", + "*/src/core/linux/SDL_sandbox.c", + "*/src/core/linux/SDL_threadprio.c", + "*/src/core/linux/SDL_udev.c", + "*/src/core/unix/*.c", + "*/src/filesystem/unix/*.c", + "*/src/haptic/linux/*.c", + "*/src/joystick/linux/*.c", + "*/src/loadso/dlopen/*.c", + "*/src/locale/unix/*.c", + "*/src/misc/unix/*.c", + "*/src/power/linux/*.c", + "*/src/thread/pthread/*.c", + "*/src/timer/unix/*.c", + "*/src/video/x11/*.c", + }, + -- The X11 set compat.glfw already proves out. xorgproto carries + -- ; the rest are the extensions the config block above + -- switches on (XCursor, Xext for XDBE/XShape, XFixes, XInput2, + -- XRandR) plus Xinerama, which SDL probes for. + deps = { + -- glx-headers, not compat.opengl: SDL's X11 driver includes + -- , which the Khronos registry does not carry. The two + -- packages overlap on GL/gl.h, so exactly one of them belongs + -- here — see the note in compat.glx-headers. + ["compat.glx-headers"] = "1.7.0", + ["compat.x11"] = "1.8.13", + ["compat.xcursor"] = "1.2.3", + ["compat.xext"] = "1.3.7", + ["compat.xfixes"] = "6.0.2", + ["compat.xi"] = "1.8.3", + ["compat.xinerama"] = "1.1.6", + ["compat.xorgproto"] = "2025.1", + ["compat.xrandr"] = "1.5.5", + ["compat.xrender"] = "0.9.12", + }, + ldflags = { "-lpthread", "-ldl", "-lm" }, + runtime = { + capabilities = { "x11.display" }, + }, + }, + + macosx = { + -- Cocoa, CoreAudio and the IOKit joystick/haptic backends are + -- Objective-C, hence the .m globs alongside the .c ones. + sources = { + "*/src/audio/coreaudio/*.m", + "*/src/file/cocoa/*.m", + "*/src/filesystem/cocoa/*.m", + "*/src/haptic/darwin/*.c", + "*/src/joystick/darwin/*.c", + -- SDL_JOYSTICK_MFI is on in upstream's macosx config, and + -- SDL_gamecontroller.c calls into it (IOS_SupportedHIDDevice, + -- IOS_GameControllerGetAppleSFSymbolsName*). The directory is + -- named iphoneos but serves macOS too. + "*/src/joystick/iphoneos/*.m", + "*/src/loadso/dlopen/*.c", + "*/src/locale/macosx/*.m", + "*/src/misc/macosx/*.m", + "*/src/power/macosx/*.c", + "*/src/render/metal/*.m", + "*/src/thread/pthread/*.c", + "*/src/timer/unix/*.c", + "*/src/video/cocoa/*.m", + }, + -- ARC is not optional on Apple: SDL's cocoa classes declare + -- `__weak SDL_WindowData *_data`, and a __weak ivar without ARC is + -- rejected outright ("'_data' is unavailable"). Upstream's CMake + -- hard-fails when the compiler cannot do -fobjc-arc, for this + -- reason. It applies to the .m files, which mcpp routes through + -- cflags along with the .c ones. + cflags = { "-fobjc-arc" }, + ldflags = { + "-framework", "Cocoa", + "-framework", "CoreFoundation", + "-framework", "CoreAudio", + "-framework", "AudioToolbox", + "-framework", "CoreVideo", + "-framework", "IOKit", + "-framework", "ForceFeedback", + "-framework", "Carbon", + "-framework", "Metal", + "-framework", "QuartzCore", + "-framework", "CoreHaptics", + "-framework", "GameController", + -- Foundation/CoreFoundation for CF* (CFRelease and friends); + -- SystemConfiguration for SCDynamicStoreCopyProxies, which + -- SDL's URL/misc code uses. + "-framework", "Foundation", + "-framework", "SystemConfiguration", + "-lpthread", "-lm", + }, + }, + + windows = { + sources = { + "*/src/audio/directsound/*.c", + "*/src/audio/wasapi/*.c", + "*/src/audio/winmm/*.c", + "*/src/core/windows/*.c", + "*/src/filesystem/windows/*.c", + "*/src/haptic/windows/*.c", + "*/src/joystick/windows/*.c", + "*/src/loadso/windows/*.c", + "*/src/locale/windows/*.c", + "*/src/misc/windows/*.c", + "*/src/power/windows/*.c", + "*/src/sensor/windows/*.c", + -- thread/windows, plus exactly one file from thread/generic. + -- The windows condition-variable backend (SDL_syscond_cv.c) + -- falls back to the generic implementation, so + -- SDL_CreateCond_generic & co. have to be linked. Only that one + -- file: generic's SDL_sysmutex.c / SDL_syssem.c / + -- SDL_systhread.c / SDL_systls.c share basenames with the + -- windows set, and mcpp keys objects by basename in one flat + -- per-link directory (mcpp#233), so pulling the whole directory + -- would have them silently displace each other. SDL_syscond.c + -- has no windows twin, so it is safe. + "*/src/thread/generic/SDL_syscond.c", + "*/src/thread/windows/*.c", + "*/src/timer/windows/*.c", + "*/src/video/windows/*.c", + }, + -- SDL_audiocvt.c carries runtime-dispatched SSE3 converters, and + -- clang refuses to inline `_mm_hadd_ps` into a function compiled + -- without the target feature (gcc is lenient here, which is why + -- Linux never saw it). Upstream applies the flag per file; so do we, + -- rather than raising the ISA floor for the whole library. + flags = { + { glob = "*/src/audio/SDL_audiocvt.c", cflags = { "-msse3" } }, + }, + ldflags = { + "-luser32", "-lgdi32", "-lwinmm", "-limm32", + "-lole32", "-loleaut32", "-lshell32", "-lsetupapi", + "-lversion", "-luuid", "-ladvapi32", + }, + }, + }, +} diff --git a/pkgs/c/compat.vulkan-headers.lua b/pkgs/c/compat.vulkan-headers.lua new file mode 100644 index 0000000..64c4420 --- /dev/null +++ b/pkgs/c/compat.vulkan-headers.lua @@ -0,0 +1,68 @@ +-- compat.vulkan-headers — Khronos Vulkan API headers. +-- +-- Header-only, the same shape as `compat.opengl`: expose `include/` and carry a +-- trivial anchor TU so the package still produces a buildable lib target. +-- Split out from `compat.vulkan` (the loader) because they are separate +-- upstream repositories on separate release cadences, and because a consumer +-- that only needs the types — a renderer compiled against a loader it does not +-- link, say — should not drag the loader in. +-- +-- `vk_video/` ships alongside `vulkan/` and is included by `vulkan_video.h`, so +-- one include root covers both. +-- +-- Versioning follows the Vulkan SDK release the tag belongs to +-- (`vulkan-sdk-1.4.357.0` → `1.4.357.0`), which is how Khronos ties the header, +-- loader and validation-layer repos together. +package = { + spec = "1", + namespace = "compat", + name = "vulkan-headers", + description = "Khronos Vulkan API headers", + licenses = {"Apache-2.0"}, + repo = "https://github.com/KhronosGroup/Vulkan-Headers", + type = "package", + + xpm = { + linux = { + ["1.4.357.0"] = { + url = { + GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz", + }, + sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3", + }, + }, + macosx = { + ["1.4.357.0"] = { + url = { + GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz", + }, + sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3", + }, + }, + windows = { + ["1.4.357.0"] = { + url = { + GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz", + }, + sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + include_dirs = { "*/include" }, + generated_files = { + ["mcpp_generated/vulkan_headers_anchor.c"] = + "int mcpp_compat_vulkan_headers_anchor(void) { return 0; }\n", + }, + sources = { "mcpp_generated/vulkan_headers_anchor.c" }, + targets = { ["vulkan-headers"] = { kind = "lib" } }, + deps = {}, + }, +} diff --git a/pkgs/c/compat.vulkan.lua b/pkgs/c/compat.vulkan.lua new file mode 100644 index 0000000..3022ab6 --- /dev/null +++ b/pkgs/c/compat.vulkan.lua @@ -0,0 +1,189 @@ +-- compat.vulkan — the Khronos Vulkan loader, built from source as a static lib. +-- +-- This is the thing a Vulkan program LINKS: `vkCreateInstance` and friends are +-- trampolines the loader owns, which then dispatch into whatever ICD (GPU +-- driver) the system advertises. Headers alone are not enough, which is why +-- `compat.vulkan-headers` is a separate package this one depends on. +-- +-- Buildable as a plain source list — no CMake, no Python, no assembler: +-- +-- * `loader/generated/` (vk_loader_extensions.c, vk_object_types.h, …) is +-- CHECKED IN upstream, so the codegen step CMake would run is unnecessary. +-- * The assembly path is optional. Upstream's CMake compiles +-- `dev_ext_trampoline.c` + `phys_dev_ext.c` against hand-written GAS/MASM +-- and a generated `gen_defines.asm` (which needs building and RUNNING +-- asm_offset, then a Python script to scrape its output). That whole chain +-- is gated on `UNKNOWN_FUNCTIONS_SUPPORTED`; upstream itself degrades +-- gracefully when no working assembler is found, and +-- `unknown_function_handling.c` compiles a pure-C fallback instead. We take +-- that fallback deliberately: the cost is that unknown DEVICE extension +-- entry points (ones this loader version has never heard of) get no +-- trampoline, which no consumer in this index uses. +-- +-- WINDOWS IS DEFERRED. A statically linked loader is not something upstream +-- supports there: the only static option in its CMake is `APPLE_STATIC_LOADER`, +-- gated to macOS and carrying the warning that it "will only work on MacOS and +-- is not supported" elsewhere. Built anyway, the Windows loader links but faults +-- at the first entry point (0xC0000005 out of vkEnumerateInstanceVersion). Linux +-- is not covered by that option either, but a static loader is the ordinary +-- case there and works — Chromium ships one. Rather than carry a package that +-- crashes, this follows `compat.openssl` and declares no windows xpm entry; +-- consumers gate with `[target.'cfg(...)']`. +-- +-- SYSCONFDIR / FALLBACK_*_DIRS are the ICD and layer manifest search paths. +-- Upstream's CMake derives them from the install prefix; the values below are +-- the FHS/XDG defaults, which is what a system-installed driver actually uses — +-- this package must find the HOST's ICDs, not any path of its own. +-- +-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*/` absorbs +-- the GitHub tarball's `Vulkan-Loader-vulkan-sdk-1.4.357.0/` wrap layer. +package = { + spec = "1", + namespace = "compat", + name = "vulkan", + description = "Khronos Vulkan loader — static ICD-dispatch library", + licenses = {"Apache-2.0"}, + repo = "https://github.com/KhronosGroup/Vulkan-Loader", + type = "package", + + xpm = { + linux = { + ["1.4.357.0"] = { + url = { + GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/vulkan/releases/download/1.4.357.0/vulkan-1.4.357.0.tar.gz", + }, + sha256 = "54f2537df22313768da0317dda2abdaaab7711b4081c48c869a79db343d0ae70", + }, + }, + macosx = { + ["1.4.357.0"] = { + url = { + GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/vulkan/releases/download/1.4.357.0/vulkan-1.4.357.0.tar.gz", + }, + sha256 = "54f2537df22313768da0317dda2abdaaab7711b4081c48c869a79db343d0ae70", + }, + }, + -- windows deferred, see the note at the top of this file. + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + + include_dirs = { "*/loader", "*/loader/generated", "mcpp_generated" }, + + -- SYSCONFDIR / FALLBACK_*_DIRS have to reach the compiler as STRING + -- literals, and `-DSYSCONFDIR="/etc"` does not survive the trip: mcpp + -- splits flags without honouring the quotes (mcpp#234), so loader.c + -- ends up seeing a bare `/etc` and fails with "expected expression + -- before '/' token". Carrying them in a force-included header sidesteps + -- the command line entirely — the same move `compat.opencv5` made for + -- its space-bearing defines. + generated_files = { + ["mcpp_generated/mcpp_vulkan_paths.h"] = [==[ +/* Manifest search paths for the Vulkan loader — see the descriptor note. */ +#pragma once +#define SYSCONFDIR "/etc" +#define FALLBACK_CONFIG_DIRS "/etc/xdg" +#define FALLBACK_DATA_DIRS "/usr/local/share:/usr/share" +]==], + }, + + -- Upstream NORMAL_LOADER_SRCS, minus the OPT_LOADER_SRCS pair that only + -- builds with the assembly path (see the header note). + sources = { + "*/loader/allocation.c", + "*/loader/cJSON.c", + "*/loader/debug_utils.c", + "*/loader/extension_manual.c", + "*/loader/gpa_helper.c", + "*/loader/loader.c", + "*/loader/loader_environment.c", + "*/loader/loader_json.c", + "*/loader/log.c", + "*/loader/settings.c", + "*/loader/terminator.c", + "*/loader/trampoline.c", + "*/loader/unknown_function_handling.c", + "*/loader/wsi.c", + }, + + targets = { ["vulkan"] = { kind = "lib" } }, + deps = { ["compat.vulkan-headers"] = "1.4.357.0" }, + + -- VK_ENABLE_BETA_EXTENSIONS is not optional despite the name: the + -- checked-in generated/vk_object_types.h references + -- VK_OBJECT_TYPE_CUDA_MODULE_NV, which the headers only declare under + -- this macro. Without it the loader does not compile at all. + cflags = { "-DVK_ENABLE_BETA_EXTENSIONS" }, + + linux = { + -- LOADER_ENABLE_LINUX_SORT is what upstream sets alongside + -- loader_linux.c: it sorts physical devices by PCI bus info so + -- device 0 is the discrete GPU rather than whichever ICD replied + -- first. + sources = { "*/loader/loader_linux.c" }, + cflags = { + "-D_GNU_SOURCE", + "-DHAVE_ALLOCA_H", + "-DLOADER_ENABLE_LINUX_SORT", + "-DVK_USE_PLATFORM_XLIB_KHR", + "-DVK_USE_PLATFORM_XCB_KHR", + "-include", "mcpp_vulkan_paths.h", + }, + -- The two VK_USE_PLATFORM_X*_KHR defines make vulkan_xlib.h / + -- vulkan_xcb.h pull in and , so the X + -- headers are a COMPILE dependency of the loader here, not just of + -- whoever creates the surface. xorgproto carries , which + -- Xlib.h includes. Only headers are needed — the loader never links + -- against Xlib; the ICD does. + deps = { + ["compat.x11"] = "1.8.13", + ["compat.xcb"] = "1.17.0", + ["compat.xorgproto"] = "2025.1", + }, + -- dlopen for the ICDs and layers; pthread for the loader's locks. + ldflags = { "-ldl", "-lpthread", "-lm" }, + runtime = { + -- The loader itself is linked statically, but a Vulkan program + -- is still useless without an installed ICD. Model that as a + -- capability rather than pretending a vendor driver is a + -- redistributable package — same call `compat.glfw` makes for + -- `opengl.glx.driver` (see the GL runtime plan doc). + capabilities = { "vulkan.icd.driver" }, + }, + }, + + macosx = { + -- No loader_linux.c and no LINUX_SORT. VK_USE_PLATFORM_METAL_EXT + -- costs nothing here: vulkan_metal.h typedefs CAMetalLayer to void + -- outside an Objective-C TU, so it needs no Metal SDK to compile. + cflags = { + "-D_GNU_SOURCE", + -- Both surface platforms, not just Metal: wsi.c `#error`s with + -- "VK_USE_PLATFORM_MACOS_MVK not defined!" when only one of the + -- pair is present on Apple. + "-DVK_USE_PLATFORM_METAL_EXT", + "-DVK_USE_PLATFORM_MACOS_MVK", + -- Upstream's own switch for a statically linked loader; it is + -- what makes the entry points resolve without the DLL-style + -- export table. + "-DAPPLE_STATIC_LOADER", + "-include", "mcpp_vulkan_paths.h", + }, + -- CoreFoundation for CFRelease & friends: the loader reads bundle + -- paths when it looks for ICDs. + ldflags = { "-framework", "CoreFoundation", "-lpthread", "-lm" }, + runtime = { + -- macOS has no native Vulkan; the ICD is MoltenVK, layered over + -- Metal. The loader loads it exactly like any other ICD. + capabilities = { "vulkan.icd.driver" }, + }, + }, + + -- No `windows` block: see the deferral note at the top. + }, +} diff --git a/tests/examples/curl/mcpp.toml b/tests/examples/curl/mcpp.toml new file mode 100644 index 0000000..12fb073 --- /dev/null +++ b/tests/examples/curl/mcpp.toml @@ -0,0 +1,10 @@ +[package] +name = "curl-tests" +version = "0.1.0" + +# Deliberately NO -DCURL_STATICLIB here: compat.curl publishes it itself, via a +# `default` feature that implies one carrying the define. If that ever stops +# working, reverts to dllimport declarations and the Windows link +# fails — which is the point of not spelling it out on this side. +[dependencies.compat] +curl = "8.21.0" diff --git a/tests/examples/curl/tests/transfer.cpp b/tests/examples/curl/tests/transfer.cpp new file mode 100644 index 0000000..0c21644 --- /dev/null +++ b/tests/examples/curl/tests/transfer.cpp @@ -0,0 +1,89 @@ +// Behavioral test — verify compat.curl builds a usable libcurl with working +// TLS, without touching the network. +// +// CI runners have no reliable outbound network and the index's other members +// never assume one, so nothing here opens a connection. What is asserted +// instead is everything that a misconfigured build actually gets wrong: +// +// * the library initialises at all (curl_global_init walks the same setup +// path a real transfer would), +// * the TLS backend is really compiled in — a curl built with no SSL still +// links and still runs, it just silently cannot do https, which is exactly +// the failure EUI-NEO's `network` feature would hit at runtime, +// * https and http are among the supported protocols, +// * a handle can be configured with the options EUI-NEO actually sets. +#include +import std; + +// CURL_STATICLIB must arrive from the PACKAGE, not from this project. Without +// it declares everything __declspec(dllimport) and the Windows +// link fails against a static archive; on other platforms it is inert, so this +// compile-time check is the only thing that catches a regression early. +static_assert([] { +#if defined(CURL_STATICLIB) + return true; +#else + return false; +#endif +}(), "CURL_STATICLIB did not reach the consumer — compat.curl stopped publishing it"); + +int main() { + if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { + std::println("curl_global_init failed"); + return 1; + } + + const curl_version_info_data* info = curl_version_info(CURLVERSION_NOW); + if (info == nullptr) { + std::println("curl_version_info returned null"); + curl_global_cleanup(); + return 2; + } + + // The whole point of wiring a TLS backend. `ssl_version` is null when curl + // was built without one. + if ((info->features & CURL_VERSION_SSL) == 0 || info->ssl_version == nullptr) { + std::println("libcurl built WITHOUT TLS — https would fail at runtime"); + curl_global_cleanup(); + return 3; + } + + bool haveHttps = false; + bool haveHttp = false; + for (const char* const* p = info->protocols; p != nullptr && *p != nullptr; ++p) { + const std::string_view proto{*p}; + if (proto == "https") haveHttps = true; + if (proto == "http") haveHttp = true; + } + if (!haveHttp || !haveHttps) { + std::println("missing protocol support (http={}, https={})", haveHttp, haveHttps); + curl_global_cleanup(); + return 4; + } + + // The exact option set core/platform/network.cpp configures. A handle that + // rejects any of these would break the `network` feature. + CURL* handle = curl_easy_init(); + if (handle == nullptr) { + std::println("curl_easy_init failed"); + curl_global_cleanup(); + return 5; + } + const bool optionsOk = + curl_easy_setopt(handle, CURLOPT_URL, "https://example.invalid/") == CURLE_OK && + curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L) == CURLE_OK && + curl_easy_setopt(handle, CURLOPT_TIMEOUT, 15L) == CURLE_OK && + curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L) == CURLE_OK; + curl_easy_cleanup(handle); + + if (!optionsOk) { + std::println("curl_easy_setopt rejected an option EUI-NEO relies on"); + curl_global_cleanup(); + return 6; + } + + std::println("compat.curl: ok ({}, ssl={}, http+https present)", + info->version, info->ssl_version); + curl_global_cleanup(); + return 0; +} diff --git a/tests/examples/sdl2/mcpp.toml b/tests/examples/sdl2/mcpp.toml new file mode 100644 index 0000000..3c90ad2 --- /dev/null +++ b/tests/examples/sdl2/mcpp.toml @@ -0,0 +1,6 @@ +[package] +name = "sdl2-tests" +version = "0.1.0" + +[dependencies.compat] +sdl2 = "2.32.10" diff --git a/tests/examples/sdl2/tests/video.cpp b/tests/examples/sdl2/tests/video.cpp new file mode 100644 index 0000000..c2c65e1 --- /dev/null +++ b/tests/examples/sdl2/tests/video.cpp @@ -0,0 +1,95 @@ +// Behavioral test — verify compat.sdl2 builds an SDL that can actually run a +// video subsystem, create a window and pump events. +// +// SDL is the one backend in this family that CAN be exercised headlessly: +// its `dummy` video driver is a real, fully functional driver that just never +// touches a display. So unlike the OpenGL and Vulkan backends, this is not a +// link-only smoke test — SDL_Init, SDL_CreateWindow, SDL_GetWindowSize and the +// event pump all execute. +// +// The driver is selected through SDL_HINT_VIDEODRIVER rather than the +// SDL_VIDEODRIVER environment variable so the test is self-contained and does +// not depend on how CI invokes it. +// SDL_MAIN_HANDLED before : on Windows SDL_main.h does +// `#define main SDL_main` and expects the real entry point to come from +// SDL2main (src/main/windows/SDL_windows_main.c). This package does not ship +// that — a library consumer should not be handed an entry point — so the test +// takes SDL's documented alternative and keeps its own main, pairing it with +// SDL_SetMainReady() below. Without this the link fails with +// "LNK1561: entry point must be defined". +#define SDL_MAIN_HANDLED +#include +import std; + +int main() { + SDL_SetMainReady(); + SDL_SetHint(SDL_HINT_VIDEODRIVER, "dummy"); + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { + std::println("SDL_Init failed: {}", SDL_GetError()); + return 1; + } + + // A build whose video subsystem never registered a driver fails here, which + // is the failure mode a bad SDL_config.h produces — upstream's Linux + // fallback config (SDL_config_minimal.h) builds exactly that. + const char* driver = SDL_GetCurrentVideoDriver(); + if (driver == nullptr) { + std::println("no video driver active: {}", SDL_GetError()); + SDL_Quit(); + return 2; + } + + SDL_Window* window = SDL_CreateWindow( + "compat.sdl2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + 320, 240, SDL_WINDOW_HIDDEN); + if (window == nullptr) { + std::println("SDL_CreateWindow failed: {}", SDL_GetError()); + SDL_Quit(); + return 3; + } + + int width = 0; + int height = 0; + SDL_GetWindowSize(window, &width, &height); + if (width != 320 || height != 240) { + std::println("unexpected window size: {}x{}", width, height); + SDL_DestroyWindow(window); + SDL_Quit(); + return 4; + } + + // Pumping events exercises the event subsystem end to end; SDL_QUIT is + // pushed and read back rather than waited for, so nothing here can hang. + SDL_Event pushed{}; + pushed.type = SDL_QUIT; + if (SDL_PushEvent(&pushed) < 0) { + std::println("SDL_PushEvent failed: {}", SDL_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 5; + } + SDL_PumpEvents(); + + bool sawQuit = false; + SDL_Event event{}; + while (SDL_PollEvent(&event) != 0) { + if (event.type == SDL_QUIT) sawQuit = true; + } + if (!sawQuit) { + std::println("pushed SDL_QUIT never came back out of the event queue"); + SDL_DestroyWindow(window); + SDL_Quit(); + return 6; + } + + SDL_version linked{}; + SDL_GetVersion(&linked); + + std::println("compat.sdl2: ok (SDL {}.{}.{}, driver={}, {}x{} window, events round-tripped)", + linked.major, linked.minor, linked.patch, driver, width, height); + + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; +} diff --git a/tests/examples/vulkan/mcpp.toml b/tests/examples/vulkan/mcpp.toml new file mode 100644 index 0000000..5f96ae5 --- /dev/null +++ b/tests/examples/vulkan/mcpp.toml @@ -0,0 +1,19 @@ +# linux + macOS only: compat.vulkan has no windows xpm entry (a statically +# linked Vulkan loader is not supported there upstream — see the note at the top +# of pkgs/c/compat.vulkan.lua). On windows this member carries no dependency and +# tests/loader.cpp compiles to a no-op main(). +[package] +name = "vulkan-tests" +version = "0.1.0" + +[target.'cfg(linux)'.dependencies.compat] +vulkan = "1.4.357.0" + +[target.'cfg(linux)'.build] +cxxflags = ["-DHAVE_VULKAN_LOADER=1"] + +[target.'cfg(macos)'.dependencies.compat] +vulkan = "1.4.357.0" + +[target.'cfg(macos)'.build] +cxxflags = ["-DHAVE_VULKAN_LOADER=1"] diff --git a/tests/examples/vulkan/tests/loader.cpp b/tests/examples/vulkan/tests/loader.cpp new file mode 100644 index 0000000..88ab193 --- /dev/null +++ b/tests/examples/vulkan/tests/loader.cpp @@ -0,0 +1,77 @@ +// Behavioral test — verify compat.vulkan builds a working loader and that a +// consumer can link its trampolines. +// +// Everything asserted here is answered by the LOADER itself, before any ICD is +// involved, so it is meaningful on a CI runner with no GPU and no driver. +// That constraint is sharper than it looks: the loader advertises the WSI +// surface extensions only when some ICD supports them, so `VK_KHR_surface` is +// legitimately ABSENT on a driverless machine and asserting on it would just be +// testing the runner's hardware. +// +// HAVE_VULKAN_LOADER is set by THIS project's own [target.'cfg(...)'.build] +// cxxflags, because compat.vulkan has no windows entry. A consumer that keys +// its source off a dependency's presence has to declare that itself. +#if defined(HAVE_VULKAN_LOADER) +#include +#endif +import std; + +#if !defined(HAVE_VULKAN_LOADER) +int main() { + std::println("compat.vulkan: skipped (no windows build — static loader unsupported upstream)"); + return 0; +} +#else +int main() { + // Only the loader can answer this — it reports the Vulkan version the + // loader itself implements. A package that failed to compile its + // trampolines fails at LINK here rather than passing quietly. + std::uint32_t apiVersion = 0; + if (vkEnumerateInstanceVersion(&apiVersion) != VK_SUCCESS) { + std::println("vkEnumerateInstanceVersion failed"); + return 1; + } + if (VK_VERSION_MAJOR(apiVersion) < 1) { + std::println("implausible loader api version: {}", apiVersion); + return 2; + } + + std::uint32_t extensionCount = 0; + if (vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr) != VK_SUCCESS) { + std::println("vkEnumerateInstanceExtensionProperties failed"); + return 3; + } + std::vector extensions(extensionCount); + if (extensionCount > 0 && + vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data()) != VK_SUCCESS) { + std::println("vkEnumerateInstanceExtensionProperties (fill) failed"); + return 4; + } + + // VK_EXT_debug_utils is implemented BY the loader, so it is present with or + // without a driver — unlike the surface extensions. Its absence would mean + // the loader's own extension table never made it into the lib. + const bool haveDebugUtils = std::ranges::any_of(extensions, [](const VkExtensionProperties& e) { + return std::string_view(e.extensionName) == VK_EXT_DEBUG_UTILS_EXTENSION_NAME; + }); + if (!haveDebugUtils) { + std::println("VK_EXT_debug_utils missing from {} loader extension(s)", extensionCount); + for (const auto& e : extensions) std::println(" {}", e.extensionName); + return 5; + } + + // Link-time proof that wsi.c is in the library. vkDestroySurfaceKHR is a + // WSI trampoline; referencing it makes a build without that translation + // unit fail to link, which is the check the extension list cannot give us + // on a driverless machine. + if (&vkDestroySurfaceKHR == nullptr) { + std::println("vkDestroySurfaceKHR unexpectedly null"); + return 6; + } + + std::println("compat.vulkan: ok (loader api {}.{}.{}, {} loader extension(s), WSI trampolines linked)", + VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), + VK_VERSION_PATCH(apiVersion), extensionCount); + return 0; +} +#endif