Skip to content

Latest commit

 

History

History
41 lines (37 loc) · 32.2 KB

File metadata and controls

41 lines (37 loc) · 32.2 KB

Descriptor examples by shape

English | 简体中文

The complete catalog of .lua descriptors in this index, grouped by the shape of the problem each one solves. It is meant to be read the way you would read a case book: find the row whose situation matches yours, open that descriptor, and reuse its reasoning. Every entry records not just what the package compiles but what it deliberately does not, which is usually the part worth copying.

For the templates behind each shape see package-types.md; the short list of starting points lives in the root README.

Shape Examples
Native module library (Form A) mcpplibs.xpkg · mcpplibs.tinyhttps · tensorvia-cpu · ffmpeg (module layer; sources compiled directly through compat.ffmpeg) · opencv (single repository: the module layer and the full OpenCV 5 source build both live in the package, and only this descriptor stays on the index side) · mcpplibs.grpc (gRPC 1.83.0 — the one library here that CANNOT be a compat descriptor: upstream publishes no self-contained source artifact, its tag archive carrying abseil/protobuf/re2/boringssl/zlib as empty submodule placeholders, so grpc-m's release tarball IS that artifact. It vendors only gRPC's own source and takes the five dependencies from this index, so a consumer that also uses protobuf links one copy rather than two)
C-source compat (with features) compat.cjson · compat.zlib · compat.hiredis (the classic 1.2.0 — a 7-TU C build whose flat tarball headers get hiredis/-prefixed wrapper headers via generated_files, so consumers write #include <hiredis/hiredis.h> exactly like upstream's install layout) · compat.sqlite3 (plain C-source, no features: the single sqlite3.c amalgamation; 3.45.3, the final maintenance release of the most widely deployed 3.45.x line) · compat.libuv (libuv 1.48.0 — the per-OS source sets transcribed from upstream's CMakeLists, because a src/unix/*.c glob would compile every OS's backend at once; linux/macos get explicit unix subsets, windows globs src/win/*.c)
C-source compat where the library IS a kernel ABI compat.libaio (libaio 0.3.113 — twelve syscall-wrapper TUs, and the only xpm section is linux, because there is no port to declare: struct iocb is the kernel's and every TU is syscall(__NR_io_*, …). Consumers gate it with [target.'cfg(linux)'.dependencies], the mirror image of compat.wil. Three things it teaches. One public header out of a source dir: upstream installs exactly one, libaio.h, but the tarball keeps it in src/ beside the private headers — one of which is named syscall.h and would SHADOW glibc's for every consumer TU — so include_dirs names a generated_files forwarder and nothing else; the package's own sources reach the real header through it while their quote-form #include "syscall.h" still resolves next to the including .c, so no -I into src/ is needed at all. A c_standard that is a trap: -std=c11 sets __STRICT_ANSI__, which hides syscall() and sigset_t, and the public header then fails to parse at io_pgetevents; declaring c_standard = "gnu11" LOOKS like the fix but mcpp 2026.8.27.2 accepts the string and still emits -std=c11 (visible in the emitted compile_commands.json), so -D_GNU_SOURCE in cflags is the spelling that takes effect. Symbol versioning in a static package: io_getevents and io_cancel have no ordinary definitions upstream — the functions are io_getevents_0_4 etc. publishing short names through .symver … @@LIBAIO_0.4 — which resolves for an executable under both ld.bfd and lld, but not when a consumer builds a .so straight out of these objects; that needs upstream's src/libaio.map, exactly as upstream's own libaio.a does)
C++-source compat, one depending on the other compat.abseil (151 TUs; a wildcard over absl/** trimmed by upstream's test/benchmark naming conventions) · compat.protobuf (the libprotobuf runtime, 79 TUs transcribed from upstream's own src/file_lists.cmake; declares compat.abseil as a dependency because protobuf's public headers include absl/…, and its gzip feature defines HAVE_ZLIB and pulls compat.zlib, while upb adds protobuf's 64-TU C runtime out of the same tarball. It also exposes protoc as a kind = "bin" target, so a consumer writing tools = ["protoc"] gets the compiler built for its own machine out of the same package it links — making a generator/runtime version mismatch inexpressible) · compat.re2 (22 TUs, upstream's own RE2_SOURCES) · compat.redis-plus-plus (redis++ 1.3.13 — the sync client, 17 TUs + patterns/redlock.cpp, depends on compat.hiredis; the one header CMake would generate, hiredis_features.h, is snapshotted via generated_files, and the async/TLS TUs are left out so the base build stays a two-package pair. An async feature adds the libuv-backed AsyncRedis interface (the 9 async TUs + compat.libuv; event_loop.cpp runs uv_run on a background thread, and <hiredis/adapters/libuv.h> arrives through compat.hiredis' wrapper headers). Two versions, one on each side of the source-structure watershed, share this ONE source list: 1.3.13 (modern 17-TU layout) and 1.3.3 (pre-redis_uri.cpp/redlock 15-TU layout) — the union works because 1.3.3's TUs are a strict subset, so exactly two globs match nothing there (a warning, not an error; same trick as compat.catch2))
C transport + the header-only C++ server on top of it compat.usockets · compat.uwebsockets (uSockets picks ONE event loop for all three platforms — libuv, via compat.libuv — because the alternative makes us_loop_t a different struct per platform for no gain; SSL and QUIC are left out so the base package's only dependency is that loop. The pair's real lesson is that LIBUS_USE_LIBUV / LIBUS_NO_SSL / UWS_NO_ZLIB are INTERFACE facts: libusockets.h changes the layout of us_loop_t under the first and gates its SSL declarations on the second, and uWS is header-only so its templates are instantiated in the CONSUMER's translation unit. An index descriptor's cflags reach only the package's own TUs, so every consumer must declare all three — a mismatch does not fail to build, it corrupts. The usockets test therefore writes to loop-attached extension memory from a timer callback and reads it back, which is exactly the assertion a layout disagreement breaks)
C++-source compat, zero-dep client + optional components compat.websocket (IXWebSocket 12.0.1 — a pure RFC 6455 client compiled from upstream's IXWEBSOCKET_SOURCES minus the four server TUs, so the base build has zero external dependencies: TLS off (the OpenSSL/MbedTLS/AppleSSL TUs aren't built) and IXWEBSOCKET_USE_ZLIB unset, so the gzip codec compiles to a no-op. Two optional features add on top: server (the four server TUs — IXWebSocketServer, IXSocketServer, IXHttpServer, IXWebSocketProxyServer — needing nothing external, and it implies zlib because upstream's server advertises permessage-deflate by default, which the transport negotiates regardless of the define) and zlib (deps compat.zlib and turns the codec into real per-message-deflate compression). The default-feature test brings its own minimal RFC 6455 echo server on loopback sockets (handshake, masking, fragmentation and close all exercised offline); a second member, websocket-features, runs a real ix::WebSocketServer and asserts the compression is observable on the wire — a 64 KiB repeated payload round-trips with wireSize = 80)
Database client + the driver manager it needs, built from source compat.nanodbc (nanodbc 2.14.0, frozen upstream — one TU over the platform ODBC driver manager. Two fixes make the four-year-old source compile and RUN here: a force-included char_traits<unsigned char> shim for libc++ (the standard's own customization point, guarded on _LIBCPP_VERSION so libstdc++/MSVC are untouched; and note -include reaches C++ TUs only through cxxflags, never cflags), and a per-platform answer to the manager itself — windows links the SDK's odbc32, macOS the OS's iODBC, while linux takes compat.unixodbc because mcpp's runtime closure rejects a NEEDED libodbc.so.2 that only the host has. The test asserts the manager's own diagnostics surface through the wrapper — including nanodbc's frozen off-by-one that drops the last SQL-state character) · compat.unixodbc (unixODBC 2.3.14, Shape E over A — DM + odbcinst + ini/log/lst + libltdl compiled statically into one odbc target, exactly upstream's libodbc.a symbol set, so the consumer carries no libodbc.so.2 NEEDED at all. The one non-obvious piece is libtool-free ltdl wiring: -DLTDLOPEN=libltdlc plus a generated lt_libltdlc_LTX_preloaded_symbols table (reconstructed from the libtool object's relocations) registers the dlopen loader. The frozen config.h merges ltdl's own configure output into the top-level one — ltdl sources never read the clashing identification macros, and the merge sidesteps a quoted -DLT_CONFIG_H that does not survive the pipeline. Verified against the libtool build of the same tarball: identical IM002 error path and identical lt_dlopen behaviour)
C-source compat, an ISA tier turned off through the GENERATED config compat.libwebp (117 TUs as five directory globs rather than a transcribed file list, and one real decision. libwebp's SSE4.1 gate is `(SSE4_1
header-only (with features) compat.eigen · compat.concurrentqueue (moodycamel's lock-free MPMC queue 1.0.5 — three public headers at the tarball root, so * plus an anchor TU is the package. The ONE compilable optional component, c_api/'s two extern "C" wrapper TUs, sits behind a c-api feature, and the Windows story is why the descriptor carries cxxflags = {"-DMOODYCAMEL_STATIC"} beside the feature's defines: the header defaults to __declspec(dllimport) unless told otherwise, which is wrong for both the package's own TUs (they DEFINE the functions — and cflags would never reach a .cpp) and a static-archive consumer; the macro is read only inside #ifdef _WIN32, so defining it everywhere is inert on linux/macos. Everything else upstream ships outside the library is either header-only (nothing to gate) or carries a main()/benchmarks, which a lib target cannot take — its objects enter the consumer's link eagerly)
header-only, nothing to gate compat.CLI11 (a command line parser whose every definition is CLI11_INLINE, so the package is */include plus an anchor TU. Upstream's two extras stay out: src/Precompile.cpp only means anything when CLI11_COMPILE also reaches the CONSUMER's translation units — an interface define, not a sources-only gate — and src/modules/CLI11.cppm is a module layer, which is a package shape of its own rather than a feature of the compat package) · compat.gtl (Greg's Template Library — the Swiss-table flat_hash_map family plus btrees and a bit_vector. */include exactly, not the tarball root: tests/ and examples/ carry headers of their own, and naming include/ is what upstream's INTERFACE target exposes, so a consumer cannot accidentally resolve into test code) · compat.plf-hive (the reference implementation of the proposed std::hive; the whole library is one file at the tarball root, so * plus an anchor TU is the entire package. Untagged upstream, so the version is a DATE over a commit archive — the compat.khrplatform precedent) · compat.wil (the Windows Implementation Library — RAII over Win32 handles, COM pointers and HRESULT. Windows-ONLY in an unusual sense: not a portable library with a Windows backend, but a library ABOUT Win32, so there are no other platform sections to declare and consumers gate the dependency with [target.'cfg(windows)'.dependencies] — compat.x11 and the gui-stack member in the other direction. Nothing is pre-configured: WIL's knobs (WIL_ENABLE_EXCEPTIONS, RESULT_DIAGNOSTICS_LEVEL, WIL_USE_STL) are macros the CONSUMER defines before including, and a header-only package has no compiled artifact for such a choice to be baked into anyway — pre-setting one would pick an error model on its consumers' behalf)
single-header library + a GENERATED implementation TU compat.nanosvg (two stb-style headers where the implementation hides behind NANOSVG_IMPLEMENTATION / NANOSVGRAST_IMPLEMENTATION. Upstream ships no .c — its examples define the macros inline — so the package generates one that instantiates BOTH halves once. That is what turns a header drop into something linkable, and it moves the duplicate-symbol hazard from every consumer to a single place: consumers must NOT define those macros again, and the test links nsvgParse and nsvgRasterize together precisely so a package that instantiated only one half fails here rather than downstream) · compat.vulkan-memory-allocator (VMA 3.4.0, same shape but the generated TU also has to make a POLICY choice. VMA defaults to VMA_STATIC_VULKAN_FUNCTIONS 1, which references vkBindBufferMemory2 and seven siblings by name — eight undefined symbols against a headers-only dep. Pulling compat.vulkan to satisfy them would force a Vulkan loader on every consumer of a memory allocator and fight anyone dispatching through volk, so the generated TU selects the dynamic path instead and VMA resolves everything through VmaVulkanFunctions. Note the implementation is C++ despite the C-shaped API, so the generated file is .cpp)
Runtime loader compat (pure sources, sidestepping upstream codegen/asm) compat.vulkan (the Khronos loader: loader/generated/ is checked in, and the assembly path degrades to plain C through UNKNOWN_FUNCTIONS_SUPPORTED, so no CMake/Python/assembler is needed; windows deferred) · compat.vulkan-headers
Whole-source direct build + generated config (only where a platform lacks one) compat.curl (win32 uses upstream's checked-in config, unix generates one) · compat.sdl2 (win/mac use upstream's checked-in config; linux generates one and enables X11 by hand) · compat.c-ares (91 TUs; the release tarball already ships ares_build.h and a Windows config, so only ares_config.h is snapshotted per OS) · compat.msdfgen (msdfgen 1.13 — the config is not optional here: core/base.h opens with #include <msdfgen/msdfgen-config.h>, so without generating it nothing compiles, not even core/. Generating it rather than passing -D flags is also what makes the library and its consumers agree BY CONSTRUCTION — base.h is reached from every public header, so the file is the single place that says which of SVG/PNG/Skia exist. Of the four ext/ units only import-font.cpp is built; the other three each need a library this index does not carry, and their declarations disappear through the same generated config. MSDFGEN_USE_CPP11 is left off on purpose: it adds move constructors to Bitmap, so it changes the layout of a type that crosses the library boundary, and a package cannot guarantee every consumer defines it identically)
Upstream amalgamation (one TU is the whole library) compat.harfbuzz (HarfBuzz 14.3.0 — upstream builds with meson, and reproducing that here would mean tracking ~137 .cc files plus a generated config. src/harfbuzz.cc is upstream's own supported "compile one file" path, so sources is a single line that cannot drift out of sync with a release. The amalgamation also #includes the CoreText/DirectWrite/GDI/GLib/Graphite2 backends, each behind its own HAVE_* gate, so naming only HAVE_FREETYPE selects the FreeType bridge and compiles the rest to nothing. HB_NO_MT is deliberately NOT set: it removes HarfBuzz's atomics, which is only sound under a single-threading promise a shared package cannot make for its consumers) · compat.mimalloc (mimalloc 3.4.5 — the opposite lesson: it also ships an amalgamation (src/static.c), and using it would be wrong. A src/*.c glob is wrong three ways, each a LINK error rather than a compile error — static.c duplicates every symbol, and free.c/alloc-override.c are #included by alloc.c rather than being TUs — so the source list is upstream's own mi_sources. MI_MALLOC_OVERRIDE stays off: a dependency silently taking over the process allocator is not a package's call) · compat.miniaudio (miniaudio 0.11.25 — miniaudio.c is upstream's own two-line MINIAUDIO_IMPLEMENTATION driver and its CMake library target, so sources is one line that tracks the release. The Linux link line is -ldl -lpthread -lm and deliberately NOT -lasound/-lpulse: miniaudio dlopens its backends, so the package builds on a machine that has neither) · compat.spirv-reflect (Khronos' SPIR-V reflection library; spirv_reflect.c is exactly upstream's spirv-reflect-static target. Both * and */include are exposed so the default "./include/spirv/unified1/spirv.h" and the SPIRV_REFLECT_USE_SYSTEM_SPIRV_H spelling resolve to the SAME bundled grammar header — a consumer that defines that macro cannot silently get a different SPIR-V revision than this .c was written against. Versioned by SDK line to stay in step with compat.vulkan-headers)
Upstream codegen frozen into the mirror archive compat.godot-cpp (two versions: 4.5.0 = the godot-4.5-stable bindings, 10.0.0-rc1 = godot-cpp's own 10.x line, whose bindings target Godot 4.6. The ~1000 GDExtension classes under gen/ exist in no upstream tag archive — upstream's binding_generator.py emits them at build time. Running it once offline and publishing upstream's tree byte-for-byte plus gen/ keeps Python off the consumer side entirely; tools/godot-cpp/repack.sh reproduces the archive deterministically and refuses to publish if any upstream file differs)
Header package filling a gap in the index compat.glx-headers (libglvnd's GL/glx.h, absent from the Khronos registry and required by SDL's X11 backend)
C++ application framework compat (dependencies reuse packages already in the index) compat.eui-neo (upstream's 3rd/ ships 8 vendored dependencies; none of them is compiled here — all are redirected to the same-version compat.* packages in this index)
Mutually exclusive backends (one of several inside one package) compat.eui-neo: vulkan / sdl2 each replace the default OpenGL / GLFW, and the default backend is expressed by naming no feature at all — there is no opengl/glfw feature. A default feature cannot express exclusivity: its own defines/sources/deps have no effect whatsoever, while its implies always applies and cannot be overridden by a named feature (which is, conversely, exactly the solution for the "always-on interface define" row below). The workable answer is to read the -DMCPP_FEATURE_<NAME> mcpp passes anyway and decide up front in a force-included header. Note also that cflags only reaches C TUs — C++ needs cxxflags, so a backend define written only into cflags never reaches any .cpp
Host runtime adaptation (drivers are not vendored) compat.glx-runtime · compat.vulkan-runtime (mcpp binaries run against a bundled glibc, so a bare-soname dlopen never reaches the host drivers; a symlink farm plus runtime.library_dirs bridges that. The farm holds only versioned sonames, so nothing there can shadow an index package. Note that runtime.library_dirs renders as -Wl,-rpath and not as -L — the -L key is runtime.link_library_dirs, which these two do not need because nothing links against their farms; see the row below for one that does)
Ecosystem-stack binding (zero host) compat.libgbm (Mesa's GBM — buffer allocation out of a DRM device. The row above reaches the HOST; this one reaches the ECOSYSTEM and nothing else, and the distinction is the whole design. Why not a source build: libgbm is a build target inside Mesa, not a project — src/gbm/meson.build is link_with: [libloader], and libloader wants idep_mesautil, the whole of Mesa's internal util library (~120 TUs plus Python-generated tables) for exactly one function, loader_open_driver_lib. Building it would make this index re-import libdrm + expat + xcb + a Mesa-util carve-out to duplicate what xim:mesa has already resolved hermetically. Contrast compat.vulkan, which does build the Khronos loader from source — Khronos releases that as a standalone project, Mesa releases no such thing for GBM. Zero host, with no escape hatch: unlike its two neighbours it has no /usr/lib* path and no MCPP_HOST_* override, because host libgbm is a leak the ecosystem already closed — xim:nvidia-gl-host-link names it directly ("the table … was missing libm, libdrm, libgbm, libgcc_s … all of which were therefore coming from the HOST, silently, which is the leak this package exists to close"). NVIDIA's own GBM backend, if ever needed, belongs in that host-link layer rather than here. The measured surface is 1 ecosystem package (xim:mesa, not xim:graphics's twenty-two), zero index deps, and zero transitive burden — libgbm.so.1's own RUNPATH resolves entirely inside xim-x-*. What it deliberately does NOT do: set the backend search path. libgbm is a loader — gbm_create_device() dlopens <path>/<driver>_gbm.so, and Mesa's compiled-in /usr/lib/gbm is right on a distro and wrong the moment the payload is relocated. The mechanism to fix that is Mesa's own (GBM_BACKENDS_PATH) and the job belongs to the ENVIRONMENT, which is where every other relocated stack puts it — Valve's pressure-vessel answers the identical breakage with GBM_BACKENDS_PATH=/run/host/usr/lib64/gbm (steam-runtime#797), Nix and Conda set it at activation. In this ecosystem xim:mesa now declares it through the graphics discovery layer (openxlings/xim-pkgindex#713), so this package sets nothing, generates no TU and ships no header of its own. It briefly did carry a constructor that set the variable itself; that was a workaround for the missing declaration, and deleting it took the descriptor from 598 lines to 303. Two directory keys, not one: library_dirs renders as -Wl,-rpath and link_library_dirs as -L, so a package that is linked against (unlike glx-runtime/vulkan-runtime, whose farms are only dlopen'd) needs both — with library_dirs alone the farm is complete, the rpath correct, and the build still dies at ld: cannot find -lgbm. It ships two test binaries: stock_usage.cpp includes stock <gbm.h> and nothing else, which is the minimal consumer and the tripwire on the two things outside this repo the package now depends on — xim-pkgindex's DISCOVERY row and mcpp's subos-env injection · compat.libdrm (the layer under GBM — drmModeAddFB2/drmModeSetCrtc turn an allocated buffer into a scanout. Passes the separable-unit test that libgbm fails — libdrm is an independent freedesktop project and Conan carries a real recipe — but is still a binding for the second reason: xim:libdrm exists, Mesa's own payload has DT_NEEDED on it, and two libdrm.so.2 in one process means two DRM handle tables. Two include roots, which is the thing that bites: the public headers sit at the include root and the uapi headers they include sit under libdrm/, and xf86drm.h line 40 is a bare #include <drm.h> — expose one root and nothing compiles at all) · compat.egl (what makes libgbm useful for RENDERING rather than only allocation: eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, gbm_device, NULL). Provider is libglvnd, not Mesa — EGL is a spec and the thing you link is a vendor-neutral dispatch library that must be the only one in the process. Ships only EGL/ out of a payload that also carries GL/, GLES2/, KHR/: a third provider of GL/ would make compat.glx-headers' documented two-provider race a three-way one, and KHR/ comes from the index's existing compat.khrplatform instead — load-bearing, since eglplatform.h opens with #include <KHR/khrplatform.h>. X11 is deliberately NOT a dependency: that include is USE_X11-gated, and forcing Xorg on headless GBM users would be exactly wrong) · compat.wayland (client, server, cursor and EGL shim all harvested, but only -lwayland-client on ldflags. A dependency's ldflags reach the consumer's link line with no way to opt out, so forcing the server library on every client would be unfixable downstream; a compositor author adds -lwayland-server themselves and it resolves out of the farm. The test member does exactly that, so the documented escape hatch has a regression guarding it. wayland-scanner and the protocol XML are NOT here — that is a code generator plus a data package, the compat.protobuf protoc shape, and a separate package))
Always-on interface define CURL_STATICLIB in compat.curl: cflags is always on but package-private, while a feature's defines reaches consumers yet has to be named — default = { implies = … } applies unconditionally and happens to give both
Multiple majors in one package (shape switches with the version) compat.catch2 (3.x compiles src/catch2/ into a static library; 2.x goes header-only through single_include/)
External build system (install() builds from source) compat.openblas (Make) · compat.openssl (Perl Configure + Make, static libssl/libcrypto)
Whole-source direct build (config snapshot + source list, no external build system) compat.ffmpeg (2281 TUs including NASM assembly, declared through 28 directory globs)
Build-time generator output vendored into the descriptor compat.gmp (516 TUs, all three platforms. GMP's build COMPILES AND RUNS seven table generators and substitutes gmp.h from gmp-h.in — all of it a pure function of limb=64/nail=0, so the outputs are produced once by upstream's own generators and shipped in generated_files (~270 KB, of which trialdivtab.h is 109 KB). That is what removes the install() hook, autotools, and the host compiler its probes needed — and with them the reason windows was deferred, since GMP's generic C only ever needed a GCC-compatible compiler. generated_files also carries a one-line forwarding header per source directory, so the package compiles with no -I at all and include_dirs exposes gmp.h + gmpxx.h rather than GMP's private headers. Verified against a --disable-assembly autotools build of the same tarball: identical 598-symbol export set, and GMP's own make check passes 177/178 against it)
Module layer over a compat source build (external Form-A repo) godotengine.godot-cpp-m (two versions tracking upstream: 10.0.0-rc1 = Godot 4.6, 4.5.0 = Godot 4.5. import godot_cpp; re-exports the whole godot namespace, ~1800 names GENERATED from the headers rather than curated; the 1022-TU build stays in compat.godot-cpp, so the index carries only this descriptor. Macros — GDCLASS, GDREGISTER_CLASS, memnew, ERR_* — are the one thing a named module cannot export, so the package ships a side header to include next to the import. It also ships a generated hashfuncs.hpp shim — upstream's header minus static on two functions whose bodies declare an unnamed union — without which GCC refuses the module interface outright, a hard error no -W flag reaches)
C++23 module wrapper nlohmann.json · marzer.tomlplusplus · neargye.magic_enum · boost-ext.ut (upstream's own include/boost/ut.cppm reproduced verbatim but for one __argc/__argv shim that Clang-on-MSVC needs; namespace boost-ext since it is NOT an official Boost library)