|
| 1 | +# `deps-vcpkg`, `deps-cmake` and `deps-archive` |
| 2 | + |
| 3 | +The `deps-*` members answer where a library comes from: a vcpkg manifest, a CMake subproject, or an archive the project keeps. Each installation is an action with declared inputs and outputs, and the prefix reaches the build by name (include directory, libraries by full path, runtime search directory), so planning installs nothing. |
| 4 | + |
| 5 | +## `deps-vcpkg` |
| 6 | + |
| 7 | +Module `mcpp.deps.vcpkg`; engine floor: 2026.9.26.2 (mcpp#702). |
| 8 | + |
| 9 | +**Needs and behaviour.** `xim:vcpkg` (the tool and the scripts released with it), which this feature declares on the host axis, and `tools = ["mcpp-deps"]` on the edge. From 0.13.0. Installs a `vcpkg.json` manifest as a `prepare` action and maps `<install root>/<triplet>/<triplet>` into the build by name, its shared-library directory a runtime search directory; `mcpp emit build-database` installs nothing. See [the section below](#deps-vcpkg-the-libraries-a-vcpkg-manifest-names) |
| 10 | + |
| 11 | +## `deps-cmake` |
| 12 | + |
| 13 | +Module `mcpp.deps.cmake`; engine floor: 2026.9.26.2 (mcpp#702). |
| 14 | + |
| 15 | +**Needs and behaviour.** `xim:cmake`, which this feature declares on the host axis, and `tools = ["mcpp-deps"]` on the edge. From 0.13.0. Configures, builds and installs a CMake subproject as one `prepare` action whose inputs are the subproject's files, and maps the prefix as `deps-vcpkg` does |
| 16 | + |
| 17 | +## `deps-archive` |
| 18 | + |
| 19 | +Module `mcpp.deps.archive`; engine floor: 2026.9.26.2. |
| 20 | + |
| 21 | +**Needs and behaviour.** `xim:cmake`, which this feature declares on the host axis, and `tools = ["mcpp-deps"]` on the edge. From 0.14.0. Extracts a zip archive the project keeps and places its tree beside the program: one action names every member as an output, read from the archive's central directory while the build program runs, and each is deployed, so `mcpp run` finds the files and `mcpp pack` carries them. See [the section below](#deps-vcpkg-the-libraries-a-vcpkg-manifest-names) |
| 22 | + |
| 23 | +## `deps-vcpkg`: the libraries a vcpkg manifest names |
| 24 | + |
| 25 | +```toml |
| 26 | +[build-dependencies.mcpp] |
| 27 | +plugins = { version = "0.14.1", features = ["deps-vcpkg"], host-module = true, tools = ["mcpp-deps"] } |
| 28 | +``` |
| 29 | + |
| 30 | +```cpp |
| 31 | +// build.mcpp |
| 32 | +import std; |
| 33 | +import mcpp; |
| 34 | +import mcpp.deps.vcpkg; |
| 35 | + |
| 36 | +int main() { |
| 37 | + mcpp::deps::vcpkg::options o; |
| 38 | + o.libraries = { "fmt", "spdlog" }; |
| 39 | + return mcpp::deps::vcpkg::use(o) ? 0 : 1; |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +`use()` finds `vcpkg.json` at or above the package root, so every member of a |
| 44 | +workspace finds a manifest kept at the workspace root. It then: |
| 45 | + |
| 46 | +- declares `mcpp-deps vcpkg …` as a `mcpp::roles::prepare` action whose output |
| 47 | + directory is the prefix `<install root>/<triplet>/<triplet>` and whose inputs are `vcpkg.json`, |
| 48 | + `vcpkg-configuration.json` and every file of the manifest's overlay ports and |
| 49 | + triplets. The package's compile and link edges wait for it; it runs under |
| 50 | + `mcpp build` when an input changed, and never under `mcpp emit |
| 51 | + build-database`; |
| 52 | +- adds `<prefix>/include` as an include directory; |
| 53 | +- links each name in `options::libraries` by its full path under |
| 54 | + `<prefix>/lib` (`fmt` is `fmt.lib` on Windows, `libfmt.a` or |
| 55 | + `libfmt.so` elsewhere; a name with an extension is a file name); |
| 56 | +- for a triplet that links dynamically, declares `bin/` (Windows) or `lib/` |
| 57 | + (elsewhere) with `mcpp::runtime_search_dir`: the program's run path on ELF and |
| 58 | + Mach-O, `mcpp run`'s load path, `mcpp pack`'s closure, and on Windows the |
| 59 | + DLLs the program imports placed beside it after the link; |
| 60 | +- copies each file `options::deploy` names out of the prefix, by an action |
| 61 | + that names the copy as its output, and deploys the copy beside the program; |
| 62 | +- returns the prefix (`root`, `include`, `lib`, `bin`, `share`, `triplet`, and |
| 63 | + `deployed`, the copies, for a project that lays out a directory of its own). |
| 64 | + |
| 65 | +A vcpkg tool that is not installed is a warning and not a failure: the plan |
| 66 | +states every path it can, and the build is where the absence fails. |
| 67 | + |
| 68 | +| option | meaning | |
| 69 | +|---|---| |
| 70 | +| `triplet` | empty derives it from the target: `x64-windows`, `arm64-windows`, `x64-mingw-dynamic`, `x64-linux`, `arm64-linux`, `x64-osx`, `arm64-osx`; on Linux under a libc++ toolchain the generated `x64-linux-libcxx` or `arm64-linux-libcxx` (0.14.1); a custom triplet is found through the manifest's `overlay-triplets` | |
| 71 | +| `libraries` | the link, in order; a name that matches no installed file fails the link, naming its path | |
| 72 | +| `manifest_root` | the directory holding `vcpkg.json` | |
| 73 | +| `install_root` | empty is vcpkg's default, `<manifest root>/vcpkg_installed`. Each triplet is its own vcpkg installation, `<install root>/<triplet>`, because vcpkg's manifest mode removes from an installation the packages of every other triplet (0.14.1; 0.14.0's prefix `<install root>/<triplet>` is no longer read) | |
| 74 | +| `overlay_triplets` | further overlay-triplet directories | |
| 75 | +| `install_args` | arguments appended to `vcpkg install` | |
| 76 | +| `vcpkg_root` | a vcpkg root other than the `xim:vcpkg` payload | |
| 77 | +| `deploy` | files of the prefix the program reads at run time, each `{file, to}`: `file` relative to the prefix root, `to` the directory beside the program (`{"share/opencc/t2s.json", "BaseConfig/opencc"}`) | |
| 78 | + |
| 79 | +The payload `xim:vcpkg` is vcpkg-tool's release binary with the standalone |
| 80 | +bundle published beside it, so the scripts a port calls are the ones that tool |
| 81 | +was released with. A `builtin-baseline` manifest resolves through vcpkg's git |
| 82 | +registry, into vcpkg's per-user registry cache; no clone of microsoft/vcpkg is |
| 83 | +made per project, and an inherited `VCPKG_ROOT` is not used. `mcpp-deps` |
| 84 | +places vcpkg's downloads and each installation's build trees in vcpkg's |
| 85 | +per-user directory (`%LOCALAPPDATA%\vcpkg` on Windows, `$XDG_CACHE_HOME/vcpkg` |
| 86 | +or `~/.cache/vcpkg` elsewhere), beside vcpkg's default binary cache, and takes |
| 87 | +an exclusive lock on the installation root while vcpkg runs. vcpkg fetches its |
| 88 | +own CMake, Ninja and 7-Zip, and on Windows a portable git; on Linux and macOS |
| 89 | +its documented host prerequisites (git, curl, zip, unzip, tar, a C compiler) |
| 90 | +are the host's. Ports are compiled with vcpkg's default toolchain for the |
| 91 | +triplet: the Visual Studio toolset on Windows, the host compiler elsewhere. The |
| 92 | +program links them, so its C++ standard library must be theirs. On Windows every |
| 93 | +compiler of the MSVC ABI, mcpp's clang included, uses Microsoft's, and on macOS |
| 94 | +every compiler uses libc++, so a port links as it stands. Linux has two |
| 95 | +libraries that do not link with each other: the host compiler uses libstdc++, |
| 96 | +and mcpp's clang uses libc++ (`std::__1::`). Under a libc++ toolchain the |
| 97 | +default triplet is therefore a generated one, `<arch>-linux-libcxx`, whose |
| 98 | +ports build with mcpp's clang through vcpkg's chain-loaded toolchain file; the |
| 99 | +clang's own configuration names libc++ and the C library mcpp links against. |
| 100 | +Under a gcc toolchain the default triplet is vcpkg's own (0.14.1). |
| 101 | + |
| 102 | +Not supported: vcpkg's classic mode; the debug libraries under `debug/lib`. |
| 103 | + |
| 104 | +## `deps-cmake`: a CMake subproject |
| 105 | + |
| 106 | +```cpp |
| 107 | +import mcpp.deps.cmake; |
| 108 | + |
| 109 | +int main() { |
| 110 | + mcpp::deps::cmake::options o; |
| 111 | + o.source = "3rdParty/widgets"; |
| 112 | + o.cache_args = { "-DWIDGETS_BUILD_EXAMPLES=OFF" }; |
| 113 | + o.libraries = { "widgets" }; |
| 114 | + o.shared = true; |
| 115 | + return mcpp::deps::cmake::use(o) ? 0 : 1; |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +One `prepare` action configures, builds and installs the subproject into |
| 120 | +`<out dir>/deps-cmake/<name>/install`, its declared output directory; its inputs |
| 121 | +are the subproject's files, so an edit to the subproject rebuilds it. The prefix is mapped as `deps-vcpkg` |
| 122 | +maps its own. `layout` names install directories other than `include/`, `lib/` |
| 123 | +and `bin/`; `prefix_path` becomes `CMAKE_PREFIX_PATH` (`mcpp::rules::qt::root()` |
| 124 | +for a subproject that finds Qt); `cache_args` carries `-D…`, `-G …` and a |
| 125 | +toolchain file. The subproject is compiled with the toolchain CMake selects by |
| 126 | +default unless `cache_args` names a compiler or a toolchain file; on Linux under |
| 127 | +a libc++ toolchain the compilers are mcpp's clang, as `deps-vcpkg` builds its |
| 128 | +ports (0.14.1). `deploy` places files of the prefix |
| 129 | +beside the program, as `deps-vcpkg` takes it. |
| 130 | + |
| 131 | +## `deps-archive`: files a program reads at run time, from an archive |
| 132 | + |
| 133 | +```cpp |
| 134 | +import mcpp.deps.archive; |
| 135 | + |
| 136 | +int main() { |
| 137 | + mcpp::deps::archive::options o; |
| 138 | + o.archive = "assets/python-embed.zip"; |
| 139 | + o.to = "runtime"; |
| 140 | + return mcpp::deps::archive::unpack(o) ? 0 : 1; |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +`unpack()` reads the archive's central directory while the build program runs, |
| 145 | +so every file it holds is named before anything is extracted. One `artifact` |
| 146 | +action, `mcpp-deps unpack`, extracts it into `<out dir>/deps-archive/<name>` with |
| 147 | +`cmake -E tar xf --touch`, naming each file as an output; each file is then |
| 148 | +deployed under `to`, so `mcpp run` finds it beside the program and `mcpp pack` |
| 149 | +carries it. The action's inputs are the archive and the tool, so an edited |
| 150 | +archive is extracted again and an unchanged one is not; `mcpp emit |
| 151 | +build-database` extracts nothing. `result::files` lists the extracted copies |
| 152 | +with their paths beside the program, for a project that lays out a directory of |
| 153 | +its own. A C++ file inside the archive is data: the action's outputs never join |
| 154 | +the package's compile set. |
| 155 | + |
| 156 | +Only zip is read, because a compressed tar has no index to list without |
| 157 | +decompressing it while planning; a ZIP64 archive is refused by name, as is a |
| 158 | +member whose path would leave the extraction directory. A missing `cmake` is a |
| 159 | +warning, and the plan then extracts and deploys nothing. |
0 commit comments