Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ C library.

```toml
[dependencies]
openkal-llvm-runtime = "0.20.1"
openkal-llvm-runtime = "0.20.2"
```

> **Engine floor (mcpp 2026.11.2.1):** 0.17.0 is built over openkal-musl 0.26.0,
Expand Down Expand Up @@ -328,6 +328,22 @@ openkal-musl 0.27.3 selects openkal-linux 0.24.1 on Linux and openkal-ld 0.4.3
for an image. Linux confinement requires Landlock ABI 3 to enforce read-only
grants against raw file truncation. The runtime implementation is unchanged.

## i686 (0.20.2)

Built for `i686-linux-musl` above openkal-musl and openkal-linux on i386
(openkal 0.25.1, clause 5.5), the selection of compiler-rt differs from the
sixty-four bit one in two files. The x87 routines (`*xf*.c`, `*xc3.c`, the 80-bit
`long double`) are kept, as on x86_64: the type is real on i386 too. And
`atomic.c` is compiled: a sixty-four bit atomic on an object the compiler cannot
prove eight-byte aligned --- an `int64_t` field of a structure, which i386 aligns
to four --- is the call `__atomic_load` rather than an instruction, and the
embedded allocator's statistics make such loads (measured: `undefined symbol:
__atomic_load`). It takes its own locks and calls nothing of the system. Measured
locally above the family's i386 branches: a C++23 program with `import std`, an
exception, four `std::jthread`s, `std::format` of sixty-four bit values and a
file stream ran, and the openkal conformance suite held every observation it
made (407, none did not, the five not observed being x86_64's five).

## OpenKal 0.25 dependency group

Runtime 0.20.1 builds for FreeBSD above openkal-musl (`x86_64-freebsd-musl`,
Expand Down
19 changes: 16 additions & 3 deletions mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-llvm-runtime"
version = "0.20.1"
version = "0.20.2"
description = "LLVM's C++ runtime libraries — libc++, libc++abi and libunwind — configured for openkal-musl rather than for a host C library."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down Expand Up @@ -496,7 +496,7 @@ sources = [
[target.'cfg(any(os = "linux", os = "openkal"))'.build]
sources = [
"llvm/compiler-rt/lib/builtins/*.c",
"!llvm/compiler-rt/lib/builtins/atomic*.c",
"!llvm/compiler-rt/lib/builtins/atomic_*.c",
"!llvm/compiler-rt/lib/builtins/clear_cache.c",
"!llvm/compiler-rt/lib/builtins/emutls.c",
"!llvm/compiler-rt/lib/builtins/enable_execute_stack.c",
Expand Down Expand Up @@ -550,12 +550,25 @@ sources = [
# today, so the exclusion looked like an OS property. It is not. Sorting on the
# axis the fact actually lives on is what makes a second architecture work
# without a third copy of the list.
[target.'cfg(all(any(os = "linux", os = "openkal", os = "freebsd"), not(arch = "x86_64")))'.build]
[target.'cfg(all(any(os = "linux", os = "openkal", os = "freebsd"), not(arch = "x86_64"), not(arch = "i686")))'.build]
sources = [
"!llvm/compiler-rt/lib/builtins/*xf*.c",
"!llvm/compiler-rt/lib/builtins/*xc3.c",
]

# THE GENERIC ATOMICS ARE A THIRTY-TWO BIT WORD'S (i686; openkal 0.25.1, clause
# 5.5). A sixty-four bit atomic on an object the compiler cannot prove eight-byte
# aligned --- an `int64_t` field of a structure, which i386 aligns to four --- is
# the call `__atomic_load' rather than an instruction; the embedded allocator's
# statistics make such loads (measured: `undefined symbol: __atomic_load',
# i686-linux-musl). `atomic.c' answers them with its own locks and calls nothing
# of the system. Where the word is sixty-four bits nothing calls it, and it stays
# out, as before.
[target.'cfg(all(any(os = "linux", os = "openkal"), not(arch = "i686")))'.build]
sources = [
"!llvm/compiler-rt/lib/builtins/atomic.c",
]

[target.'cfg(os = "openkal")'.build]
# WHICH TARGET THIS IS, FOR THE ONE FILE THAT MUST KNOW IT IS AN OK IMAGE.
#
Expand Down
37 changes: 33 additions & 4 deletions tools/branch-graph.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,47 @@ branch="${1:-}"
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$root"

# Whether VERSION satisfies a caret RANGE (^a.b.c: below 1, the same minor
# version; from 1, the same major version; never below a.b.c).
in_range() {
local version="$1" floor="${2#^}"
local vM vm vp fM fm fp
IFS=. read -r vM vm vp <<< "$version"
IFS=. read -r fM fm fp <<< "$floor"
[ "$vM" = "$fM" ] || return 1
if [ "$fM" = 0 ]; then [ "$vm" = "$fm" ] && [ "$vp" -ge "$fp" ]; return; fi
[ "$vm" -gt "$fm" ] || { [ "$vm" = "$fm" ] && [ "$vp" -ge "$fp" ]; }
}

# Clones a repository of this ecosystem, preferring the branch under test when
# that repository has one of the same name.
# that repository has one of the same name. Without one, the default branch is
# taken if its version is within RANGE, the range the C library states for it;
# a default branch that has moved to a later line than the family's (openkal-
# windows 0.22 while the family names ^0.21.1, and mcpplibs.os bounds it below
# 0.22) is replaced by the newest release within the range, so the graph is one
# the resolver accepts.
fetch() {
local repo="$1" dir="$2"
local repo="$1" dir="$2" range="${3:-}"
rm -rf "$dir"
git clone --quiet "https://github.com/mcpplibs/$repo.git" "$dir"
if git -C "$dir" rev-parse --verify --quiet "origin/$branch" > /dev/null; then
git -C "$dir" checkout --quiet "origin/$branch"
printf ' %-22s %s %s\n' "$repo" "$branch" "$(git -C "$dir" rev-parse --short HEAD)"
else
return
fi
local version
version="$(sed -n 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' "$dir/mcpp.toml" | head -1)"
if [ -z "$range" ] || in_range "$version" "$range"; then
printf ' %-22s default branch %s (it has no %s)\n' \
"$repo" "$(git -C "$dir" rev-parse --short HEAD)" "$branch"
return
fi
local tag
tag="$(git -C "$dir" tag --sort=-v:refname | while read -r t; do
in_range "${t#v}" "$range" && { echo "$t"; break; }; done)"
[ -n "$tag" ] || { echo "::error::$repo has no release within $range (its default branch is $version)"; exit 1; }
git -C "$dir" checkout --quiet "$tag"
printf ' %-22s release %s, within %s (its default branch is %s)\n' "$repo" "$tag" "$range" "$version"
}

# In-place editing that both GNU and BSD sed perform identically.
Expand Down Expand Up @@ -80,7 +108,8 @@ manifests=(mcpp.toml .musl/mcpp.toml)
# The first was fixed by naming it, and the second appeared. A list written by
# hand is a list that is one entry short, so the set is read out of the manifest.
for backend in $(grep -oE '^openkal-[a-z]+ = \{ version' .musl/mcpp.toml | cut -d' ' -f1); do
fetch "$backend" ".$backend"
range="$(sed -n "s/^$backend = { version = \"\([^\"]*\)\".*/\1/p" .musl/mcpp.toml | head -1)"
fetch "$backend" ".$backend" "$range"

# The backend reaches the specification too, by whatever form its own
# manifest uses. From <root>/.<backend>/ the specification is ../.spec.
Expand Down
Loading