Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
57 changes: 50 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
os:
- ubuntu-latest
- macos-latest
- windows-latest

steps:
- name: Checkout
Expand All @@ -38,19 +39,61 @@ jobs:
submodules: recursive

- name: Show toolchain
shell: bash
run: |
cmake --version
c++ --version
if command -v c++ >/dev/null 2>&1; then c++ --version; fi
if command -v cl >/dev/null 2>&1; then cl; fi

- name: Set up Windows dependencies
if: runner.os == 'Windows'
shell: pwsh
run: |
# picotls requires pkg-config at configure time (even on Windows where
# brotli is absent); install the lightweight pkgconfiglite shim.
choco install pkgconfiglite --no-progress -y

$candidates = @(
"C:\Program Files\OpenSSL",
"C:\Program Files\OpenSSL-Win64",
"C:\OpenSSL-Win64"
)
$opensslFound = $false
foreach ($candidate in $candidates) {
if (Test-Path "$candidate\include\openssl\ssl.h") {
"OPENSSL_ROOT_DIR=$candidate" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host "OpenSSL found at $candidate"
$opensslFound = $true
break
}
}
if (-not $opensslFound) {
choco install openssl --no-progress -y
foreach ($candidate in $candidates) {
if (Test-Path "$candidate\include\openssl\ssl.h") {
"OPENSSL_ROOT_DIR=$candidate" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host "OpenSSL installed at $candidate"
break
}
}
}
Comment on lines +69 to +79

- name: Configure
run: >
cmake -S . -B build
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DOPENMOQ_PICOQUIC_SOURCE_DIR="${{ github.workspace }}/third_party/picoquic"
-DOPENMOQ_PICOTLS_SOURCE_DIR="${{ github.workspace }}/third_party/picotls"
shell: bash
run: |
args=(
cmake -S . -B build
Comment on lines 81 to +85
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
"-DOPENMOQ_PICOQUIC_SOURCE_DIR=${{ github.workspace }}/third_party/picoquic"
"-DOPENMOQ_PICOTLS_SOURCE_DIR=${{ github.workspace }}/third_party/picotls"
)
if [ -n "${OPENSSL_ROOT_DIR:-}" ]; then
args+=("-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}")
fi
"${args[@]}"

- name: Build
run: cmake --build build --parallel

- name: Test
run: ctest --test-dir build --output-on-failure
run: ctest --test-dir build -C Debug --output-on-failure
Comment thread
mondain marked this conversation as resolved.
Outdated
75 changes: 63 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
os:
- ubuntu-latest
- macos-latest
- windows-latest

steps:
- name: Checkout
Expand All @@ -45,14 +46,54 @@ jobs:
path: third_party/picotls
submodules: recursive

- name: Set up Windows dependencies
if: runner.os == 'Windows'
shell: pwsh
run: |
# picotls requires pkg-config at configure time (even on Windows where
# brotli is absent); install the lightweight pkgconfiglite shim.
choco install pkgconfiglite --no-progress -y

$candidates = @(
"C:\Program Files\OpenSSL",
"C:\Program Files\OpenSSL-Win64",
"C:\OpenSSL-Win64"
)
$opensslFound = $false
foreach ($candidate in $candidates) {
if (Test-Path "$candidate\include\openssl\ssl.h") {
"OPENSSL_ROOT_DIR=$candidate" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host "OpenSSL found at $candidate"
$opensslFound = $true
break
}
}
if (-not $opensslFound) {
choco install openssl --no-progress -y
foreach ($candidate in $candidates) {
if (Test-Path "$candidate\include\openssl\ssl.h") {
"OPENSSL_ROOT_DIR=$candidate" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host "OpenSSL installed at $candidate"
break
}
}
}
Comment on lines +70 to +80

- name: Configure
run: >
cmake -S . -B build
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DOPENMOQ_PICOQUIC_SOURCE_DIR="${{ github.workspace }}/third_party/picoquic"
-DOPENMOQ_PICOTLS_SOURCE_DIR="${{ github.workspace }}/third_party/picotls"
-DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
shell: bash
run: |
args=(
cmake -S . -B build
Comment on lines 82 to +86
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
"-DOPENMOQ_PICOQUIC_SOURCE_DIR=${{ github.workspace }}/third_party/picoquic"
"-DOPENMOQ_PICOTLS_SOURCE_DIR=${{ github.workspace }}/third_party/picotls"
-DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
)
if [ -n "${OPENSSL_ROOT_DIR:-}" ]; then
args+=("-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}")
fi
"${args[@]}"

- name: Build
run: cmake --build build --config Release --parallel
Expand All @@ -71,12 +112,22 @@ jobs:

package_root="openmoq-publisher-${version}-${RUNNER_OS}"
mkdir -p "${package_root}"
cp build/openmoq-publisher "${package_root}/"
cp README.md LICENSE "${package_root}/"
cp -R docs "${package_root}/docs"

archive="${package_root}.tar.gz"
tar -czf "${archive}" "${package_root}"
if [[ "${RUNNER_OS}" == "Windows" ]]; then
# MSVC multi-config generator places the binary under build/Release/
cp build/Release/openmoq-publisher.exe "${package_root}/"
cp README.md LICENSE "${package_root}/"
Comment on lines +116 to +119
cp -R docs "${package_root}/docs"
archive="${package_root}.zip"
7z a "${archive}" "${package_root}"
else
cp build/openmoq-publisher "${package_root}/"
cp README.md LICENSE "${package_root}/"
cp -R docs "${package_root}/docs"
archive="${package_root}.tar.gz"
tar -czf "${archive}" "${package_root}"
fi

if [[ "${version}" == v* ]]; then
echo "release_enabled=true" >> "${GITHUB_ENV}"
else
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ moqxr.code-workspace
run.log
run-trace*.log
openmoq-publisher-trace.csv
/.claude
/third_party
47 changes: 44 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ option(OPENMOQ_BUILD_TESTS "Build OpenMOQ publisher tests" ON)
option(OPENMOQ_ENABLE_PICOQUIC "Enable picoquic transport integration when picoquic is available" ON)
option(OPENMOQ_RUN_PICOQUIC_SMOKE_TESTS "Build and run picoquic loopback smoke tests" OFF)

set(OPENMOQ_PICOQUIC_SOURCE_DIR "/media/mondain/terrorbyte/workspace/github/picoquic" CACHE PATH
set(OPENMOQ_PICOQUIC_SOURCE_DIR "" CACHE PATH
"Path to a picoquic source checkout")

set(OPENMOQ_HAS_PICOQUIC OFF)
Expand Down Expand Up @@ -51,6 +51,12 @@ if(OPENMOQ_ENABLE_PICOQUIC AND EXISTS "${OPENMOQ_PICOQUIC_SOURCE_DIR}/CMakeLists
set(BUILD_PQBENCH OFF CACHE BOOL "" FORCE)
set(BUILD_LOGLIB ON CACHE BOOL "" FORCE)
set(BUILD_LOGREADER OFF CACHE BOOL "" FORCE)
if(WIN32 AND EXISTS "${OPENMOQ_PICOTLS_SOURCE_DIR}/picotlsvs/picotls")
# picotls.h includes "wincompat.h" on Windows but picotls's own CMakeLists.txt
# does not add picotlsvs/picotls to its include path. Inject it globally so
# the file is found when picotls compiles under FetchContent inside picoquic.
include_directories(BEFORE "${OPENMOQ_PICOTLS_SOURCE_DIR}/picotlsvs/picotls")
endif()
Comment thread
mondain marked this conversation as resolved.
Outdated
if(APPLE)
# picotls appends literal "(" and ")" list items when Brotli is
# discovered via pkg-config. On macOS, CMake rejects the resulting
Expand All @@ -73,6 +79,35 @@ if(OPENMOQ_ENABLE_PICOQUIC AND EXISTS "${OPENMOQ_PICOQUIC_SOURCE_DIR}/CMakeLists
# directories list when Brotli is discovered via pkg-config. CMake on
# macOS rejects those malformed source-prefixed paths during generate.
openmoq_sanitize_target_link_directories(picotls-core)
if(WIN32)
# picotls's cli, bench, and test executables use POSIX headers not available
# on Windows. Exclude them from the default build; the libraries we need
# (picotls-core, picotls-openssl, picotls-fusion) are unaffected.
foreach(_picotls_exe IN ITEMS
cli
test-openssl.t
test-minicrypto.t
test-fusion.t
test-mbedtls.t
ptlsbench
fuzz-asn1
fuzz-server-hello
fuzz-client-hello)
if(TARGET "${_picotls_exe}")
set_target_properties("${_picotls_exe}" PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
endforeach()
# picotls-core calls wintimeofday() which is only compiled inside the VS
# project files; add it explicitly for CMake Windows builds.
if(TARGET picotls-core AND EXISTS "${OPENMOQ_PICOTLS_SOURCE_DIR}/picotlsvs/picotls/wintimeofday.c")
target_sources(picotls-core PRIVATE
"${OPENMOQ_PICOTLS_SOURCE_DIR}/picotlsvs/picotls/wintimeofday.c")
endif()
# picotls-minicrypto uses the Windows BCrypt API for random bytes.
if(TARGET picotls-minicrypto)
target_link_libraries(picotls-minicrypto bcrypt)
Comment thread
mondain marked this conversation as resolved.
endif()
endif()
set(OPENMOQ_HAS_PICOQUIC ON)
else()
message(STATUS "picoquic checkout found, but picotls source was not found; building without picoquic integration")
Expand Down Expand Up @@ -101,20 +136,26 @@ target_compile_features(openmoq_publisher_lib PUBLIC cxx_std_20)

if(OPENMOQ_HAS_PICOQUIC)
target_compile_definitions(openmoq_publisher_lib PRIVATE OPENMOQ_HAS_PICOQUIC=1)
if(TARGET picohttp-core AND TARGET picoquic-log AND NOT APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
if(TARGET picohttp-core AND TARGET picoquic-log AND NOT APPLE AND NOT WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
# Linux with modern CMake: RESCAN resolves circular deps between picohttp/picoquic via --start-group/--end-group.
target_link_libraries(openmoq_publisher_lib PRIVATE "$<LINK_GROUP:RESCAN,picohttp-core,picoquic-log,picoquic-core>")
target_include_directories(openmoq_publisher_lib PRIVATE "${OPENMOQ_PICOQUIC_SOURCE_DIR}/picohttp")
else()
target_link_libraries(openmoq_publisher_lib PRIVATE picoquic-core)
endif()
if(TARGET picohttp-core AND (APPLE OR CMAKE_VERSION VERSION_LESS "3.24"))
if(TARGET picohttp-core AND (APPLE OR WIN32 OR CMAKE_VERSION VERSION_LESS "3.24"))
target_link_libraries(openmoq_publisher_lib PRIVATE picohttp-core)
target_include_directories(openmoq_publisher_lib PRIVATE "${OPENMOQ_PICOQUIC_SOURCE_DIR}/picohttp")
endif()
if(WIN32)
target_link_libraries(openmoq_publisher_lib PRIVATE ws2_32 iphlpapi)
endif()
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(openmoq_publisher_lib PRIVATE -Wall -Wextra -Wpedantic)
elseif(MSVC)
target_compile_options(openmoq_publisher_lib PRIVATE /W4 /WX- /utf-8)
endif()

add_executable(openmoq-publisher src/main.cpp)
Expand Down
62 changes: 43 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OpenMOQ Publisher

`moqxr` is a C++20 OpenMOQ publisher contribution project for Linux and macOS.
`moqxr` is a C++20 OpenMOQ publisher contribution project for Linux, macOS, and Windows.

It packages MP4 input into CMSF-style publishable objects, supports MOQT draft-specific framing for drafts 14 and 16, and can either inspect the generated publish plan locally or publish it over a picoquic-backed transport when local `picoquic` and `picotls` checkouts are available.

Expand Down Expand Up @@ -42,7 +42,7 @@ This keeps the project aligned with CMAF-style publication while reusing the sam

- `draft-ietf-moq-transport-14` is the primary target
- `draft-ietf-moq-transport-16` is represented as a secondary compatibility profile
- draft-specific assumptions are documented in [docs/protocol-mapping.md](/media/mondain/terrorbyte/workspace/github/moqxr/docs/protocol-mapping.md)
- draft-specific assumptions are documented in [docs/protocol-mapping.md](docs/protocol-mapping.md)

## Repository layout

Expand All @@ -51,62 +51,85 @@ This keeps the project aligned with CMAF-style publication while reusing the sam
- `tests`: CTest-based unit coverage
- `docs`: protocol notes and design references
- `docs/transport-plan.md`: picoquic integration plan and implementation checklist
- `.github/workflows/ci.yml`: GitHub Actions build and test workflow for Linux and macOS
- `.github/workflows/release.yml`: GitHub Actions release-build workflow that uploads Linux and macOS archives
- `.github/workflows/ci.yml`: GitHub Actions build and test workflow for Linux, macOS, and Windows
- `.github/workflows/release.yml`: GitHub Actions release-build workflow that uploads Linux, macOS, and Windows archives

## Release builds

For users who just want a prebuilt binary, GitHub Actions publishes release archives for Linux and macOS:
For users who just want a prebuilt binary, GitHub Actions publishes release archives for Linux, macOS, and Windows:

- pushing a `v*` tag builds release artifacts and attaches them to the matching GitHub Release
- running the `Release Builds` workflow manually uploads the same archives as workflow artifacts
- manual runs can also publish a GitHub Release when you provide a `release_tag` such as `v0.1.0`
- both CI and release workflows check out `private-octopus/picoquic` plus `private-octopus/picotls`, so published binaries include the picoquic transport path instead of falling back to a local-inspection-only build
- Linux and macOS archives are `.tar.gz`; Windows archives are `.zip` and contain `openmoq-publisher.exe`

## Build

### Baseline build

This is the default path for local development:
This is the default path for local development. It works on Linux, macOS, and Windows:

```bash
cmake -S . -B build -DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
cmake --build build
ctest --test-dir build --output-on-failure
```

### Build with local picoquic and picotls

If you have local checkouts at:

- `/media/mondain/terrorbyte/workspace/github/picoquic`
- `/media/mondain/terrorbyte/workspace/github/picotls`
On Windows with the Visual Studio generator, the binary lands in `build\Release\` or `build\Debug\` depending on the config passed to `--build`.

then the project will automatically compile against them.
### Build with local picoquic and picotls

Required picotls setup:
Clone picoquic and picotls to any convenient location and initialise the picotls submodules:

```bash
git -C /media/mondain/terrorbyte/workspace/github/picotls submodule update --init --recursive
git clone https://github.com/private-octopus/picoquic.git /path/to/picoquic
git clone --recurse-submodules https://github.com/private-octopus/picotls.git /path/to/picotls
```

Then configure and build normally:
Then point CMake at them:

```bash
cmake -S . -B build -DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
cmake -S . -B build \
-DOPENMOQ_PICOQUIC_SOURCE_DIR=/path/to/picoquic \
-DOPENMOQ_PICOTLS_SOURCE_DIR=/path/to/picotls \
-DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
cmake --build build
ctest --test-dir build --output-on-failure
```

**Windows additional requirements — pkg-config and OpenSSL**

picotls requires both `pkg-config` (to probe for optional brotli) and OpenSSL headers and libraries. On Windows you need to install both and tell CMake where OpenSSL is:

```powershell
# One-time: install pkg-config shim and OpenSSL (skip if already present)
choco install pkgconfiglite openssl

cmake -S . -B build `
-DOPENMOQ_PICOQUIC_SOURCE_DIR=C:\path\to\picoquic `
-DOPENMOQ_PICOTLS_SOURCE_DIR=C:\path\to\picotls `
-DOPENSSL_ROOT_DIR="C:\Program Files\OpenSSL-Win64" `
-DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=OFF
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure
```

The GitHub Actions release workflow locates OpenSSL automatically from the runner's pre-installed copy, so no manual step is needed in CI.
Comment thread
mondain marked this conversation as resolved.
Outdated

Useful CMake options:

- `-DOPENMOQ_ENABLE_PICOQUIC=ON|OFF`
- `-DOPENMOQ_PICOQUIC_SOURCE_DIR=/path/to/picoquic`
- `-DOPENMOQ_PICOTLS_SOURCE_DIR=/path/to/picotls`
- `-DOPENSSL_ROOT_DIR=/path/to/openssl` (Windows only, when OpenSSL is not on the system path)
- `-DOPENMOQ_RUN_PICOQUIC_SMOKE_TESTS=ON|OFF`

## Quick Start

If you already have a sample MP4 and just want to see what the publisher does, these are the most useful first commands:
If you already have a sample MP4 and just want to see what the publisher does, these are the most useful first commands.

> **Windows note**: replace `./build/openmoq-publisher` with `build\Release\openmoq-publisher.exe` in the examples below, and use `set OPENMOQ_PICOQUIC_TRACE=1` instead of the shell prefix form.
Comment thread
mondain marked this conversation as resolved.
Outdated

Inspect the publish plan with the default settings:

Expand Down Expand Up @@ -556,8 +579,9 @@ GitHub Actions is configured to build and test the project on:

- `ubuntu-latest`
- `macos-latest`
- `windows-latest`

The workflow runs the same CMake configure, build, and CTest steps on both platforms.
The workflow runs the same CMake configure, build, and CTest steps on all three platforms. On Windows, OpenSSL is located automatically from the runner's pre-installed copy and passed to CMake via `OPENSSL_ROOT_DIR`.

## Transport Notes

Expand Down
Loading