Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
13b2618
quest: claim quest/m1/c/package
kixelated Oct 20, 2026
1511e0e
feat(c)!: ship the generated C API as the moq-c package
kixelated Oct 20, 2026
ab531dc
Merge remote-tracking branch 'origin/main' into quest-m1-c-package
kixelated Oct 20, 2026
b8e5b49
docs(c): format MIGRATE.md
kixelated Oct 20, 2026
61c8e0c
docs: link MIGRATE entries to #6052
kixelated Oct 20, 2026
3b526ff
fix(c): find the lib64 probe package on Debian CMake and ask cargo fo…
kixelated Oct 20, 2026
186643e
Merge remote-tracking branch 'origin/main' into merge-main-6052
kixelated Oct 20, 2026
b0cffbb
fix(c): say callbacks may run during moq_shutdown, never after
kixelated Oct 20, 2026
c430b76
fix(c): run check directly from the module's default recipe
kixelated Oct 20, 2026
0d626a0
fix(c,cpp): share one moq-ffi cargo target per build tree
kixelated Oct 20, 2026
1da8558
test(c): dry-run a Ninja build that adds both c/moq and cpp/moq
kixelated Oct 20, 2026
01e5f45
ci(c): run the clang job on release PRs and nightly, like cpp.yml
kixelated Oct 20, 2026
5f571d9
fix(c,cpp): refuse CARGO_BUILD_TARGET for source builds
kixelated Oct 20, 2026
86df27f
test(c): accept a read cancelled by shutdown in the probe
kixelated Oct 20, 2026
ec97c1b
fix(c,cpp): take moq-ffi's paths from cargo and keep installs apart
kixelated Oct 20, 2026
e941ad2
Merge remote-tracking branch 'origin/main' into merge-main-6052
kixelated Oct 20, 2026
3bc9327
fix(c): document /MD for MSVC consumers and probe a Debug build
kixelated Oct 20, 2026
1558e52
Merge remote-tracking branch 'origin/main' into merge-main-6052
kixelated Oct 20, 2026
8ec2741
Merge remote-tracking branch 'origin/main' into merge-main-6052
kixelated Oct 20, 2026
734e3e8
fix(c,cpp): refuse moq-ffi source builds for a non-host target
kixelated Oct 20, 2026
a32e9ff
fix(c,cpp): find the build target relative to cargo's target directory
kixelated Oct 20, 2026
48a5dc1
doc(c): keep the unreleased 0.8 package out of the user docs
kixelated Oct 20, 2026
3cc16e6
Merge remote-tracking branch 'origin/main' into quest/m1/c/package
kixelated Oct 22, 2026
72283ad
feat(c): keep a retrying first dial's failure in the generated package
kixelated Oct 22, 2026
fb5c92b
fix(c,cpp): refuse a source build for a 32-bit or other-architecture …
kixelated Oct 22, 2026
e796364
Merge remote-tracking branch 'origin/main' into quest/m1/c/package
kixelated Oct 22, 2026
db4039d
quest(c): unblock the async failure contract once the package lands
kixelated Oct 22, 2026
7d589b0
Merge remote-tracking branch 'origin/main' into c-package-iter
kixelated Oct 23, 2026
0dcd713
docs(c): carry the hand-written ABI's newer MIGRATE entries
kixelated Oct 23, 2026
daae0a9
fix(c,cpp): compare the compiler's architecture with both native inputs
kixelated Oct 23, 2026
39c392a
test(gh): list the c workflow among the release-gate calls
kixelated Oct 24, 2026
dc05721
Merge remote-tracking branch 'origin/main' into merge-6052
kixelated Oct 25, 2026
e8b7faf
fix(c): adopt main's connection state, SETUP naming, and cut-time MIG…
kixelated Oct 25, 2026
92788c3
ci(c): install the generator pin that renders typed durations
kixelated Oct 26, 2026
a337170
Merge remote-tracking branch 'origin/main' into merge-6052
kixelated Oct 26, 2026
2884594
Merge remote-tracking branch 'origin/main' into c-package-merge
kixelated Oct 26, 2026
d496fbe
Merge remote-tracking branch 'origin/main' into quest/m1/c/package
kixelated Oct 26, 2026
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
1 change: 1 addition & 0 deletions .github/workflows/alert.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ on:
- moq.sh
- Nightly
- release-brew
- Release C
- Release Cpp
- Release Dart
- Release Dart FFI
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/c.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: C

# Builds and tests the moq C package (c/moq) with clang, outside Nix.
# platform.yml covers MSVC. `just check` already runs `just c check` with the
# dev shell's gcc; the dev shell has no clang, and adding one would change which
# compiler every other recipe gets as `cc`.
#
# Outside Nix the generator comes from `cargo install` at the tag flake.nix
# pins; see the comment there for every other place that names it.

permissions:
contents: read

on:
workflow_call:

concurrency:
group: c-${{ github.ref }}
cancel-in-progress: true

jobs:
clang:
name: C (clang)
runs-on: ubuntu-24.04
timeout-minutes: 60

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable

- uses: ./.github/actions/just

- name: Install uniffi-bindgen-cpp
run: cargo install uniffi-bindgen-cpp --locked --git https://github.com/kixelated/uniffi-bindgen-cpp --tag v0.11.0-kixelated.7+v0.32.2

- name: Check
run: just c check
env:
CC: clang
CXX: clang++
15 changes: 14 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ name: Nightly
# release PRs on them.
#
# Main PRs run no cloud CI beyond the merge queue's Check, so every
# path-filtered gate (Android, C++, WASM, X11, the audio replays, the OSS
# path-filtered gate (Android, C, C++, WASM, X11, the audio replays, the OSS
# Scanner image, platform.yml and the release dry-runs) runs here on main too,
# and release-gate.yml runs them on release PRs.
#
Expand Down Expand Up @@ -72,6 +72,9 @@ jobs:
android:
uses: ./.github/workflows/android.yml

c:
uses: ./.github/workflows/c.yml

cpp:
uses: ./.github/workflows/cpp.yml

Expand Down Expand Up @@ -579,6 +582,16 @@ jobs:
permissions:
contents: write

release-c:
name: Release C
needs: [release-shared-ffi]
if: ${{ always() && !cancelled() }}
uses: ./.github/workflows/release-c.yml
with:
reuse-native: true
permissions:
contents: write

release-moq-relay:
name: moq-relay
uses: ./.github/workflows/moq-relay.yml
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
branches: [release]
paths:
- "rs/**"
- "c/**"
- "cpp/**"
- "swift/**"
- "infra/moq-sh/**"
Expand Down Expand Up @@ -53,6 +54,7 @@ jobs:
needed: ${{ steps.scope.outputs.needed }}
rs: ${{ steps.scope.outputs.rs }}
swift: ${{ steps.scope.outputs.swift }}
c: ${{ steps.scope.outputs.c }}
cpp: ${{ steps.scope.outputs.cpp }}
obs: ${{ steps.scope.outputs.obs_compile }}
moq_sh: ${{ steps.scope.outputs.moq_sh }}
Expand All @@ -71,7 +73,7 @@ jobs:
windows:
name: Windows
needs: scope
if: needs.scope.outputs.rs == 'true' || needs.scope.outputs.cpp == 'true' || needs.scope.outputs.obs == 'true'
if: needs.scope.outputs.rs == 'true' || needs.scope.outputs.c == 'true' || needs.scope.outputs.cpp == 'true' || needs.scope.outputs.obs == 'true'
# OBS uses the Visual Studio 17 2022 CMake generator.
runs-on: windows-2022
# `main` and its merge queue write the Rust cache; see .github/actions/rust-cache.
Expand Down Expand Up @@ -103,7 +105,7 @@ jobs:
access-key-id: ${{ secrets.MBX_R2_ACCESS_KEY_ID }}
secret-access-key: ${{ secrets.MBX_R2_SECRET_ACCESS_KEY }}
- name: Install uniffi-bindgen-cpp
if: needs.scope.outputs.cpp == 'true' || needs.scope.outputs.obs == 'true'
if: needs.scope.outputs.c == 'true' || needs.scope.outputs.cpp == 'true' || needs.scope.outputs.obs == 'true'
shell: bash
run: cargo install uniffi-bindgen-cpp --locked --git https://github.com/kixelated/uniffi-bindgen-cpp --tag v0.11.0-kixelated.7+v0.32.2
- name: Rust compile and tests
Expand All @@ -114,6 +116,10 @@ jobs:
run: |
just rs windows "$CI_BASE"
just rs windows-test
- name: C
if: needs.scope.outputs.c == 'true'
shell: bash
run: just c check
- name: C++
if: needs.scope.outputs.cpp == 'true'
shell: bash
Expand Down
169 changes: 169 additions & 0 deletions .github/workflows/release-c.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: Release C

# Builds the moq C package (c/moq) for every target and publishes one archive per target to a
# c-v<version> GitHub release. moq-c-v* tags belong to the hand-written rs/moq-c crate until it
# retires.

on:
push:
tags:
- "c-v*"
# Dry-run: build everything, publish nothing. Nightly calls every release
# workflow this way so a broken build surfaces before the tag is cut.
workflow_call:
inputs:
reuse-native:
description: "Use this run's native input after its installed-consumer gate succeeds"
type: boolean
default: false
workflow_dispatch:

permissions:
contents: read

jobs:
build:
name: Build (${{ matrix.target }})
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
- target: aarch64-apple-darwin
os: macos-latest
- target: x86_64-pc-windows-msvc
os: windows-latest

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: ./.github/actions/just

- name: Install Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable

# aws-lc-rs assembles its x86_64 crypto with NASM on Windows.
- name: Install NASM
if: runner.os == 'Windows'
shell: pwsh
run: |
choco install nasm -y --no-progress
"C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

# The tag flake.nix pins; see the comment there.
- name: Install uniffi-bindgen-cpp
shell: bash
run: cargo install uniffi-bindgen-cpp --locked --git https://github.com/kixelated/uniffi-bindgen-cpp --tag v0.11.0-kixelated.7+v0.32.2

# The package version lives in c/moq/VERSION; a tag that disagrees is a mistake.
- name: Check version
if: github.ref_type == 'tag'
shell: bash
env:
TAG: ${{ github.ref_name }}
run: |
version=$(tr -d '[:space:]' < c/moq/VERSION)
if [[ "$TAG" != "c-v$version" ]]; then
echo "::error::tag $TAG does not match c/moq/VERSION ($version)"
exit 1
fi

- name: Refuse same-run input for a release tag
if: inputs.reuse-native && github.ref_type == 'tag'
run: |
echo "::error::c-v releases must use their immutable FFI_VERSION pin"
exit 1

# release-shared-ffi.yml stages and checks one default-feature input for both packages.
- name: Download validated same-run input
if: inputs.reuse-native
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
with:
name: cpp-native-${{ matrix.target }}
path: native-archive

- name: Parse prebuilt FFI version
if: inputs.reuse-native
id: ffi-version
run: just gh release parse-version moq-ffi

- name: Verify and extract validated input
if: inputs.reuse-native
shell: bash
env:
TARGET: ${{ matrix.target }}
VERSION: ${{ steps.ffi-version.outputs.version }}
run: just cpp ffi extract --version "$VERSION" --target "$TARGET" --directory native-archive --output native-input

- name: Build and package
shell: bash
env:
TARGET: ${{ matrix.target }}
PREBUILT_INPUT: ${{ inputs.reuse-native }}
run: |
args=(--target "$TARGET" --output dist)
if [[ "$PREBUILT_INPUT" == true ]]; then
args+=(--ffi-dir "$GITHUB_WORKSPACE/native-input")
fi
just c package "${args[@]}"

- name: Check packaged archive
shell: bash
env:
TARGET: ${{ matrix.target }}
run: |
version=$(tr -d '[:space:]' < c/moq/VERSION)
extension=tar.gz
[[ "$TARGET" == *-windows-* ]] && extension=zip
just c check --archive "dist/moq-c-$version-$TARGET.$extension"

- name: Upload artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: moq-c-generated-${{ matrix.target }}
path: dist/*

release:
name: Release
needs: build
if: github.ref_type == 'tag'
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- uses: ./.github/actions/just

- name: Parse version
id: parse
run: just gh release parse-version c

- name: Find previous tag
id: prev_tag
run: just gh release prev-tag c

- name: Download artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
with:
path: artifacts
merge-multiple: true

- name: Create or update release
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ github.ref_name }}
RELEASE_TITLE: "moq-c v${{ steps.parse.outputs.version }}"
RELEASE_PREV_TAG: ${{ steps.prev_tag.outputs.tag }}
run: just gh release create artifacts
16 changes: 16 additions & 0 deletions .github/workflows/release-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
android: ${{ steps.filter.outputs.android }}
api-diff: ${{ steps.filter.outputs.api-diff }}
audio-quality: ${{ steps.filter.outputs.audio-quality }}
c: ${{ steps.filter.outputs.c }}
cpp: ${{ steps.filter.outputs.cpp }}
interop: ${{ steps.filter.outputs.interop }}
moq-sh: ${{ steps.filter.outputs.moq-sh }}
Expand Down Expand Up @@ -108,6 +109,14 @@ jobs:
- "test/lib/**"
- "test/justfile"
- ".github/workflows/audio-quality.yml"
c:
- "c/**"
- "rs/moq-ffi/**"
- "sh/c/**"
- "rs/moq-c/native-libs/**"
- "cpp/moq/cmake/moq-ffi.cmake"
- "Cargo.lock"
- ".github/workflows/c.yml"
cpp:
- "cpp/moq/**"
- "cpp/justfile"
Expand Down Expand Up @@ -346,6 +355,12 @@ jobs:
if: needs.scope.outputs.audio-quality == 'true'
uses: ./.github/workflows/audio-quality.yml

c:
name: C
needs: scope
if: needs.scope.outputs.c == 'true'
uses: ./.github/workflows/c.yml

cpp:
name: C++
needs: scope
Expand Down Expand Up @@ -493,6 +508,7 @@ jobs:
- android
- api-diff
- audio-quality
- c
- cpp
- interop
- moq-sh
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ The `quest` binary comes from the kixelated/quest flake input and serves the que

| Change in | Also update |
|---|---|
| `rs/moq-ffi` | `rs/moq-c`, `{py,swift,kt,dart}/`, `go/wrapper/` (the `go/ffi` and `dart/moq_ffi` bindings regenerate automatically, but a new method needs a hand-written wrapper too, like `py/moq-rs` or `dart/moq`), `cpp/moq`, `cpp/obs/src`, `doc/lib/{py,swift,kt,go,dart,c,cpp}`, `doc/bin/obs.md` |
| `rs/moq-ffi` | `rs/moq-c`, `c/moq`, `{py,swift,kt,dart}/`, `go/wrapper/` (the `go/ffi` and `dart/moq_ffi` bindings regenerate automatically, but a new method needs a hand-written wrapper too, like `py/moq-rs` or `dart/moq`), `cpp/moq`, `cpp/obs/src`, `doc/lib/{py,swift,kt,go,dart,c,cpp}`, `doc/bin/obs.md` |
| `rs/moq-net` wire/API | `js/net`, `doc/concept`, `drafts/draft-lcurley-moq-lite.md` (if the wire spec changes) |
| `rs/hang` catalog/container (the `m2ts` section is Rust-only) | `js/hang`, `doc/concept`, `drafts/draft-lcurley-moq-hang.md` (if the format spec changes) |
| `rs/moq-auth` | `js/auth`, `doc/bin/relay/auth.md` |
Expand Down
27 changes: 27 additions & 0 deletions c/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env just --justfile
#
# The moq C package over rs/moq-ffi. Invoked from the repo root as `just c <recipe>` via the
# `mod c` import.

set working-directory := '.'

default: check

# Build the package, or check an archive, and run its installed consumers.
[no-cd]
[positional-arguments]
check *args:
{{ quote(justfile_directory() / "sh/c/check.sh") }} "$@"

# Runs in the caller's directory, so a relative `--output` means what it would
# to the script itself.

# Build and package the C package for release.
[no-cd]
[positional-arguments]
package *args:
{{ quote(justfile_directory() / "c/moq/build.sh") }} "$@"

# Remove the package builds.
clean:
rm -rf moq/build
2 changes: 2 additions & 0 deletions c/moq/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# `just c check` builds, installs, and tests here.
/build/
Loading
Loading