diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55d13bd..6d1007f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,10 @@ name: CI # selects, whose version group may name another openkal than the launcher's os. # A dispatch, or the repository variable MCPP_SOURCE_REF, may name a branch of # mcpp instead, which the latest released mcpp builds and which is then used. +# 0.23.0 measures with 2026.11.3.1: from it the std module is compiled with +# the platform's compile words, and this platform's `-fcf-protection=full` +# recorded in an importer's command and not in the module's refused the import +# (the release candidate, through MCPP_SOURCE_REF, until it is released). on: push: @@ -30,7 +34,7 @@ on: env: MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF || '' }} - MCPP_VERSION: 2026.11.2.1 + MCPP_VERSION: 2026.11.3.1 XLINGS_VERSION: v2026.10.26.1 XLINGS_NON_INTERACTIVE: '1' @@ -143,6 +147,40 @@ jobs: "$okld" bundle check "$okb" "$okrun" "$okb" one two | tee okb.log grep -q "image ok: 3 args" okb.log || { echo "::error::the okb's output"; exit 1; } + # SEALED AT ITS BASE (0.23.0): the image states a placement, and runs + # the same placed anywhere. + image=$(find target -path "*${{ matrix.arch }}-openkal*" -path '*bin*' -name image.oke -type f | head -1) + "$okld" inspect "$image" | tee inspect.log + grep -Eq '^placement +0x[0-9a-f]+, [1-8] writable' inspect.log || { echo "::error::the sealed image states no placement"; exit 1; } + OKRUN_PLACE=0 "$okrun" "$image" one two | tee anywhere.log + grep -q "image ok: 3 args" anywhere.log || { echo "::error::the image placed anywhere"; exit 1; } + + - name: A snapshot of a C++ program's initialisers (0.23.0) + working-directory: checks/snapshot + run: | + # The first start runs the initialisers and has a snapshot made; the + # next starts from it (its phases name the snapshot) and observes the + # same; a start whose named value the initialisers read differs runs + # them again, and observes its own value. + t='${{ matrix.arch }}-openkal' + py=python3; command -v python3 > /dev/null 2>&1 && python3 -c '' 2>/dev/null || py=python + mcpp build --release --target "$t" + okrun=$(mcpp self env --target "$t" --format json | $py -c 'import json,sys; print(json.load(sys.stdin)["data"]["runner"]["program"])') + image=$(find target -path "*$t*" -path '*bin*' -name snapshot.oke -type f | head -1) + export OKRUN_CACHE="$RUNNER_TEMP/okcache" + mkdir -p "$OKRUN_CACHE" + "$okrun" "$image" one | tr -d '\r' | tee first.log + grep -q -- '-- failures: 0 --' first.log || { echo "::error::the first start"; exit 1; } + for i in $(seq 100); do grep -qs '^made\|^refused' "$OKRUN_CACHE"/*.sealing && break; sleep 0.1; done + cat "$OKRUN_CACHE"/*.sealing + grep -q '^made' "$OKRUN_CACHE"/*.sealing || { echo "::error::no snapshot was made"; exit 1; } + rm -rf prof && mkdir prof + OKRUN_PROF=phases:prof "$okrun" "$image" two | tr -d '\r' | tee second.log + grep -q -- '-- failures: 0 --' second.log && grep -q 'local two' second.log || { echo "::error::the start from the snapshot"; exit 1; } + grep -q '"name": "snapshot"' prof/okprof-*.json || { echo "::error::the second start did not start from the snapshot"; exit 1; } + SNAPSHOT_CHECK_NAME=set "$okrun" "$image" three | tr -d '\r' | tee third.log + grep -q 'named: set' third.log && grep -q -- '-- failures: 0 --' third.log \ + || { echo "::error::a start whose named value differs observed the snapshot's"; exit 1; } - name: The hosted arrangement working-directory: checks/hosted diff --git a/README.md b/README.md index ccbc485..8375d62 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ mcpp pack --target x86_64-openkal --pkg-format okb # one file okrun runs | targets | `x86_64-openkal`, `aarch64-openkal` | | toolchain | `llvm@23.1.3` | | layers | `c-abi` openkal-musl (`posix`), `c++-abi` and `compiler-runtime` openkal-llvm-runtime | -| tools | `okld`, `okrun` (openkal-tools) | -| build | `-fPIC -femulated-tls -fvisibility=hidden -fasynchronous-unwind-tables`, stack-clash protection, `-ffunction-sections -fdata-sections`; on aarch64 `-ffixed-x18 -mno-outline-atomics` | -| link | `ld.lld`, entry `ok_main`, 64 KiB pages, `--gc-sections --icf=safe`, the image notes produced by `okld note-source` | -| seal | `okld note`, then `okld check --with` the shared images the program needs | +| tools | `okld`, `okrun`, `okprof` (openkal-tools) | +| build | `-fPIC -femulated-tls -fvisibility=hidden -fasynchronous-unwind-tables`, stack-clash protection, `-ffunction-sections -fdata-sections`; frame pointers, `-fstack-protector-strong -mstack-protector-guard=global`, `-ftrivial-auto-var-init=zero`, libc++'s fast hardening (0.23.0); on x86_64 `-fcf-protection=full`; on aarch64 `-ffixed-x18 -mno-outline-atomics -mbranch-protection=pac-ret+bti` (not `standard`, which clang 23 counts the guarded control stack in) | +| link | `ld.lld`, entry `ok_main`, 64 KiB pages, relative relocations packed, `--gc-sections --icf=safe`, `--build-id=sha1`, the image notes produced by `okld note-source` | +| seal | `okld note`; `okld place`, the writable segments computed for the base the image's bytes choose (openkal 0.23); then `okld check --with` the shared images the program needs | | naming | `{name}.oke`, `lib{name}.okso` | | runner | `okrun {}`, on a machine of the image's architecture; `hosts` the systems and architectures okrun is built for, where a package that needs it can run | | carrier | openkal-run, section `.oke`, entry `carrier/main.cpp`: with nothing carried the runner of a package, with an image or a zip of images the program that runs them from memory | @@ -45,6 +45,43 @@ A project overrides any group under `[target.]`, for example `[target.'cfg(platform = "openkal")'.layers] "c++-abi" = false`, and selects another platform, or none, with `platform = "..."` or `--platform`. +## What an image is observed and held by (0.23.0) + +Every frame of an image is a link of the frame-pointer chain, which the +implementation's sampler and fault report walk (openkal 0.23); a frame with an +array or an address taken is guarded by a variable the C library sets from the +environment's randomness, since an image has no thread pointer to keep a guard +in; a local variable read before it is written reads zero; libc++ checks what +its fast mode checks; indirect branches land on marks and returns are checked +(CET on x86_64; pac-ret and BTI on aarch64) where the system enforces them, and +are no-ops where it does not. An image is named by its build-id, by which a +debugger finds what `okld debug-split` keeps apart. + +0.23.1 names openkal-macos 0.21.3, whose answers to an initialiser that runs +before its own are the loader's record: a hosted program on macOS, whose C +library's initialiser reads its directories first, is given the directories it +was granted rather than the implementation's defaults (openkal-musl 0.27.1, +openkal-llvm-runtime 0.18.2 and openkal-image 0.4.2 are built over it). + +0.23.2 names openkal-musl 0.27.2 and openkal-llvm-runtime 0.18.3. The C +library's image dependency selects openkal-ld 0.4.2, matching the loader in +this platform's version group. The earlier 0.23.1 archive remains unchanged. + +These words reach every unit of the target, the std module included, from mcpp +2026.11.3.1 on, which this release requires (`[package] mcpp`): clang records +`-fcf-protection` in a module's BMI, and an earlier mcpp compiled the std module +without the platform's words, so every unit that imported it on x86_64 was +refused. + +An image of this platform states its placement, so a runner places it at a base +of the boot and can make a snapshot of its initialisers, which openkal-musl and +openkal-llvm-runtime take part in (`checks/snapshot`; openkal-image +`docs/snapshot.md`). The pages a start executes first are a property of a +program's use, not of its build: the producer of an image that has measured them +(`okprof record --what touch`) writes them with `okld touch` before it signs or +publishes the image, and lays its code out by `okprof report --order` through +its own link flag (`--symbol-ordering-file`). + ## The hosted arrangement and the host graph A host triple that selects this platform takes `[platform.hosted]`: the @@ -67,6 +104,7 @@ them is refused, naming the group and the two remedies. | `checks/image` | a project without declarations builds, runs and packs (M2 and M3) | | `checks/hosted` | the hosted arrangement runs on Linux, macOS and Windows | | `checks/host-graph` | a build program runs as an ok image | +| `checks/snapshot` | a C++ program starts from a snapshot of its initialisers, and a start whose named value differs does not | ## License diff --git a/build.mcpp b/build.mcpp index e9ee3fc..826cbb8 100644 --- a/build.mcpp +++ b/build.mcpp @@ -4,6 +4,13 @@ // `okld bundle --package`, which reads the package's mcpp-package.json // (mcpp SPEC-014 §4.5): the images of each architecture and the entry. The // okb is written beside the staged tree, in the project's `target/dist/`. +// +// ITS IMAGES STORED, OR COMPRESSED (0.23.0): stored by default, an okb whose +// images are mapped where they lie; `--compress gzip` (or `[pack] compress = +// "gzip"`, which mcpp 2026.11.3.1 and later state as MCPP_PACK_COMPRESS) stores +// them compressed, an okb kept small on disk that a runner expands into its +// cache when it first runs it --- the economy form (mcpp design 2026-11-03 +// part 4 §16). `zstd' and `xz' are a tar's, and refused. import mcpp; import mcpp.plugins; // the package reader import mcpp.plugins.platform; // provide_format @@ -12,14 +19,22 @@ import std; namespace pf = mcpp::plugins::platform; int main() { + const char* stated_compress = std::getenv("MCPP_PACK_COMPRESS"); + const std::string compress = stated_compress ? stated_compress : ""; + if (!compress.empty() && !compress.starts_with("gzip") && !compress.starts_with("none")) { + std::println(std::cerr, "openkal-platform: an okb stores its images compressed with DEFLATE (--compress gzip) " + "or as they are (--compress none); --compress {} is a tar's", compress); + return 1; + } const auto stated = pf::provide_format("okb", - [](const mcpp::plugins::package::info& p, mcpp::action& a) { + [&](const mcpp::plugins::package::info& p, mcpp::action& a) { const auto out = std::format("{}/{}-{}.okb", std::filesystem::path(p.root).parent_path().generic_string(), p.name, p.version); a.arg(mcpp::dep_bin("openkal-tools", "okld")) .arg("bundle").arg(out.c_str()) - .arg("--package").arg("${mcpp.stage_dir}") - .input((p.root + "/mcpp-package.json").c_str()) + .arg("--package").arg("${mcpp.stage_dir}"); + if (compress.starts_with("gzip")) a.arg("--compress"); + a.input((p.root + "/mcpp-package.json").c_str()) .output(out.c_str()); return true; }); diff --git a/checks/snapshot/mcpp.toml b/checks/snapshot/mcpp.toml new file mode 100644 index 0000000..75336ce --- /dev/null +++ b/checks/snapshot/mcpp.toml @@ -0,0 +1,9 @@ +# A C++ program whose initialisers build what a snapshot keeps (openkal-image +# 0.4.0, docs/snapshot.md), over this platform: the C library and the C++ +# run-time take part in it, and the image states the placement it needs. +[package] +name = "snapshot" +version = "0.1.0" + +[target.'cfg(os = "openkal")'] +platform = { path = "../.." } diff --git a/checks/snapshot/src/main.cpp b/checks/snapshot/src/main.cpp new file mode 100644 index 0000000..077699e --- /dev/null +++ b/checks/snapshot/src/main.cpp @@ -0,0 +1,62 @@ +// A program whose initialisers build strings, a map and a vector, and whose +// main then uses the standard streams, an exception, threads and their +// thread-local objects --- the same at a start from a snapshot of its +// initialisers as at one that runs them. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +std::string g_name = std::string("snapshot-") + std::to_string(42); +std::map g_table = [] { + std::map m; + for (int i = 0; i < 5000; ++i) m.emplace("key" + std::to_string(i), i * 3); + return m; +}(); +std::vector> g_strings = [] { + std::vector> v; + for (int i = 0; i < 3000; ++i) v.push_back(std::make_unique(std::string(i % 200 + 1, 'a' + i % 26))); + return v; +}(); +// Read once while the initialisers run: a snapshot records the name, and a +// start whose value differs does not use it. +const char* g_named = std::getenv("SNAPSHOT_CHECK_NAME"); +struct counted { + std::string s = "thread"; + ~counted() { ++destroyed; } + static inline std::atomic destroyed{0}; +}; +thread_local counted t_counted; + +int failures = 0; +void check(bool held, const char* what) { if (!held) { std::printf("FAIL: %s\n", what); ++failures; } } +} // namespace + +int main(int argc, char** argv) { + check(g_name == "snapshot-42", "the global string"); + check(g_table.size() == 5000 && g_table.at("key4999") == 4999 * 3, "the map"); + bool strings = g_strings.size() == 3000; + for (int i = 0; strings && i < 3000; ++i) strings = *g_strings[i] == std::string(i % 200 + 1, 'a' + i % 26); + check(strings, "the vector of strings"); + static const std::string local = std::string("local ") + (argc > 1 ? argv[1] : "none"); + std::cout << "iostream: " << g_name << " " << local << std::endl; + try { throw std::runtime_error("thrown"); } catch (const std::exception& e) { check(std::string(e.what()) == "thrown", "an exception is caught"); } + std::vector threads; + std::atomic sum{0}; + for (int k = 0; k < 4; ++k) threads.emplace_back([&] { sum += static_cast(t_counted.s.size()); }); + for (auto& t : threads) t.join(); + check(sum == 24, "the threads' thread-local objects"); + check(counted::destroyed >= 4, "and their destructors ran"); + std::printf("named: %s\n", g_named ? g_named : "(absent)"); + g_table.clear(); + g_strings.clear(); + std::printf("-- failures: %d --\n", failures); + return failures != 0; +} diff --git a/mcpp.toml b/mcpp.toml index 169aef6..1b8316f 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -12,12 +12,12 @@ [package] namespace = "mcpplibs" name = "openkal-platform" -version = "0.21.1" +version = "0.23.2" description = "The platform of ok images (-openkal): their toolchain, C library and C++ run-time, tools, compile and link conventions, seal, runner and carrier, as one versioned statement mcpp reads." license = "Apache-2.0" authors = ["mcpplibs"] repo = "https://github.com/mcpplibs/openkal-platform" -mcpp = ">=2026.11.2.1" +mcpp = ">=2026.11.3.1" [platform] targets = ["x86_64-openkal", "aarch64-openkal"] @@ -28,7 +28,7 @@ toolchain = "llvm@23.1.3" runner = { cmd = ["okrun", "{}"], host = "same-arch", hosts = ["linux-x86_64", "linux-aarch64", "macos-aarch64", "windows-x86_64"] } # `mcpp pack --mode self-contained`: a program of the packing machine that # carries the image in a section and runs it through libokrun (M3). -carrier = { package = "openkal-run@0.3.1", section = ".oke", main = "carrier/main.cpp" } +carrier = { package = "openkal-run@0.4.2", section = ".oke", main = "carrier/main.cpp" } # The `okb` package format (`mcpp pack --pkg-format okb`): the images of every # architecture as one file okrun runs (openkal-image docs/okb.md). plugin = "build.mcpp" @@ -36,15 +36,18 @@ plugin = "build.mcpp" # The C library and the C++ run-time inside an image. A package of the graph # that provides a layer takes its place (`provides`), and `false` leaves it out. [platform.layers] -compiler-runtime = "openkal-llvm-runtime@0.17.1" -"c++-abi" = "openkal-llvm-runtime@0.17.1" -c-abi = { name = "openkal-musl", version = "0.26.1", default-features = false, features = ["posix", "malloc-mimalloc"] } +compiler-runtime = "openkal-llvm-runtime@0.18.3" +"c++-abi" = "openkal-llvm-runtime@0.18.3" +c-abi = { name = "openkal-musl", version = "0.27.2", default-features = false, features = ["posix", "malloc-mimalloc"] } # Built for the building machine: `okld` writes and checks the notes, `okrun` -# runs an image. +# runs an image, `okprof` reads what a measured run recorded (0.23.0: the +# order of a start's first executions, which a producer lays its code out by +# and writes as the touch note). [platform.tools] -okld = "openkal-tools@0.3.1" -okrun = "openkal-tools@0.3.1" +okld = "openkal-tools@0.4.2" +okrun = "openkal-tools@0.4.2" +okprof = "openkal-tools@0.4.2" # Every unit of an image (SPEC 12.2): # -fPIC the image is ET_DYN and has no text relocation; @@ -66,35 +69,79 @@ okrun = "openkal-tools@0.3.1" # each function and object in a section of its own, so the # link's `--gc-sections` discards what nothing reaches at # that grain, not at a translation unit's. +# +# AND, FROM 0.23.0, WHAT A PROGRAM IS OBSERVED AND HELD BY (mcpp design +# 2026-11-03, part 4): +# -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer +# every frame is a link of the chain the implementation's +# sampler and fault report walk (openkal 0.23, entry 56); +# -fstack-protector-strong -mstack-protector-guard=global +# a frame with an array or an address taken is guarded, +# the guard a variable the C library sets from the +# environment's randomness, not a thread pointer's slot, +# which an image has none of; +# -ftrivial-auto-var-init=zero +# a local variable read before it is written reads zero; +# -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST +# the C++ library's cheap checks: an index out of bounds +# ends the program rather than reading beyond. [platform.build] -cflags = ["-fPIC", "-femulated-tls", "-fvisibility=hidden", "-fasynchronous-unwind-tables", "-Xclang", "-fstack-clash-protection", "-ffunction-sections", "-fdata-sections"] -cxxflags = ["-fPIC", "-femulated-tls", "-fvisibility=hidden", "-fasynchronous-unwind-tables", "-Xclang", "-fstack-clash-protection", "-ffunction-sections", "-fdata-sections"] +cflags = ["-fPIC", "-femulated-tls", "-fvisibility=hidden", "-fasynchronous-unwind-tables", "-Xclang", "-fstack-clash-protection", "-ffunction-sections", "-fdata-sections", + "-fno-omit-frame-pointer", "-mno-omit-leaf-frame-pointer", "-fstack-protector-strong", "-mstack-protector-guard=global", "-ftrivial-auto-var-init=zero"] +cxxflags = ["-fPIC", "-femulated-tls", "-fvisibility=hidden", "-fasynchronous-unwind-tables", "-Xclang", "-fstack-clash-protection", "-ffunction-sections", "-fdata-sections", + "-fno-omit-frame-pointer", "-mno-omit-leaf-frame-pointer", "-fstack-protector-strong", "-mstack-protector-guard=global", "-ftrivial-auto-var-init=zero", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST"] asmflags = ["-fPIC", "-femulated-tls", "-fvisibility=hidden", "-fasynchronous-unwind-tables", "-Xclang", "-fstack-clash-protection"] +# x86-64: an indirect branch lands on `endbr64` and a return is checked against +# a shadow stack, where the system enforces either (-fcf-protection=full); the +# instructions are no-ops where it does not. +[platform.build.'cfg(arch = "x86_64")'] +cflags = ["-fcf-protection=full"] +cxxflags = ["-fcf-protection=full"] +asmflags = ["-fcf-protection=full"] + # AArch64: two systems reserve the platform register, and the outlined atomic # helpers read the processor's features through an operating system's interface. +# A return address is signed and an indirect branch lands on a mark +# (-mbranch-protection=pac-ret+bti), which a processor without them executes as +# no-ops; the loader asks for the marks to be enforced where every object of the +# image carries them (openkal 0.23, KAL_EXEC_MAP_BTI). Not `standard': clang 23 +# counts the guarded control stack in it (__ARM_FEATURE_GCS_DEFAULT), whose +# unwinder needs of a C library and a system that enables the +# stack for a program, neither of which an image has --- libunwind's build +# failed on it (CI, aarch64). [platform.build.'cfg(arch = "aarch64")'] -cflags = ["-ffixed-x18", "-mno-outline-atomics"] -cxxflags = ["-ffixed-x18", "-mno-outline-atomics"] -asmflags = ["-ffixed-x18", "-mno-outline-atomics"] +cflags = ["-ffixed-x18", "-mno-outline-atomics", "-mbranch-protection=pac-ret+bti"] +cxxflags = ["-ffixed-x18", "-mno-outline-atomics", "-mbranch-protection=pac-ret+bti"] +asmflags = ["-ffixed-x18", "-mno-outline-atomics", "-mbranch-protection=pac-ret+bti"] # The link, by `ld.lld` itself: position-independent, every loadable segment # aligned to 64 KiB (the largest protection granularity among the systems), # bound now, no executable stack, both hash tables, what nothing reaches # discarded, identical functions whose address nothing takes folded into one, -# and the unwind index an unwinder finds through `dl_iterate_phdr`. +# and the unwind index an unwinder finds through `dl_iterate_phdr`; the relative +# relocations packed (`-z pack-relative-relocs`, SPEC 12.2's packed relative +# form): a loader reads clangd's 164 000 of them from 32 KiB rather than 3.9 MB +# on every start, and the image is 4 MB smaller. # An executable image is entered at `ok_main`, which its C library defines; its -# notes come from `okld note-source`; `okld note` writes its requirements and -# `okld check` accepts it, against the images it needs, before it is published. +# notes come from `okld note-source`; `okld note` writes its requirements, +# `okld place` its writable segments computed for the base it chooses from the +# image's bytes (openkal 0.23: a loader given that base applies only the +# relocations that name a symbol, and the image's read-only-after-relocation +# data are its file's pages), and `okld check` accepts it, against the images it +# needs, before it is published. An image is named by its build-id +# (`--build-id=sha1`, 0.23.0), by which a debugger finds what `okld debug-split` +# keeps apart from it. [platform.link] driver = "lld" start = "ok_main" -flags = ["-shared", "-z", "max-page-size=65536", "-z", "now", "-z", "noexecstack", - "--hash-style=both", "--gc-sections", "--icf=safe", "--eh-frame-hdr"] +flags = ["-shared", "-z", "max-page-size=65536", "-z", "pack-relative-relocs", "-z", "now", "-z", "noexecstack", + "--hash-style=both", "--gc-sections", "--icf=safe", "--eh-frame-hdr", "--build-id=sha1"] inputs = [{ from = ["okld", "note-source"], as = "ok-notes.S" }] exe = "{name}.oke" shared = "lib{name}.okso" -seal = [["okld", "note", "{}"], ["okld", "check", "{}", "--with", "{needed}"]] +seal = [["okld", "note", "{}"], ["okld", "place", "{}"], ["okld", "check", "{}", "--with", "{needed}"]] # A host triple selecting this platform (`x86_64-linux-gnu`, `aarch64-macos`, # `x86_64-windows-gnu`) takes the same C library and C++ run-time over the @@ -107,9 +154,9 @@ targets = ["x86_64-linux-gnu", "aarch64-linux-gnu", "x86_64-linux-musl", "aarc toolchain = "llvm@23.1.3" [platform.hosted.layers] -compiler-runtime = "openkal-llvm-runtime@0.17.1" -"c++-abi" = "openkal-llvm-runtime@0.17.1" -c-abi = { name = "openkal-musl", version = "0.26.1", default-features = false, features = ["posix", "malloc-mimalloc"] } +compiler-runtime = "openkal-llvm-runtime@0.18.3" +"c++-abi" = "openkal-llvm-runtime@0.18.3" +c-abi = { name = "openkal-musl", version = "0.27.2", default-features = false, features = ["posix", "malloc-mimalloc"] } # The family released together for openkal 0.17 (the 0.17.2 round: okb, the # runner's bundle and library interfaces, musl's renameat2; the 0.17.3 round: @@ -131,23 +178,27 @@ c-abi = { name = "openkal-musl", version = "0.26.1", default-features # instructions and read-only data mapped from its file; a program started # without copying its starter on Linux; 0.21.1: openkal-image 0.3.1, an okb # member whose admission was remembered is admitted without reading it, with -# openkal-musl 0.26.1 and openkal-llvm-runtime 0.17.1, which pin its loader): +# openkal-musl 0.26.1 and openkal-llvm-runtime 0.17.1, which pin its loader; +# 0.23.0, openkal 0.23: the system's null device at a started program's +# position, which openkal-musl 0.27.0 maps `/dev/null` onto (openkal 0.22); an +# image placed at its base, and realpath answered by the environment; the +# relative relocations of an image packed): # one version of each in a build (their pins are exact). [platform.versions] -openkal = "0.21.0" -openkal-linux = "0.22.0" -openkal-macos = "0.19.0" -openkal-windows = "0.17.0" -openkal-musl = "0.26.1" -openkal-llvm-runtime = "0.17.1" -openkal-ld = "0.3.1" -openkal-run = "0.3.1" -openkal-tools = "0.3.1" +openkal = "0.23.0" +openkal-linux = "0.24.0" +openkal-macos = "0.21.3" +openkal-windows = "0.19.0" +openkal-musl = "0.27.2" +openkal-llvm-runtime = "0.18.3" +openkal-ld = "0.4.2" +openkal-run = "0.4.2" +openkal-tools = "0.4.2" # The plugin's tool, `okld bundle`, which writes the okb, and its library, the # provider of a package format (mcpp.plugins.platform). [build-dependencies] -openkal-tools = { version = "0.3.1", tools = ["okld"] } +openkal-tools = { version = "0.4.2", tools = ["okld"] } [build-dependencies.mcpp] plugins = { version = "0.20.0", features = ["plugins-platform"], host-module = true }