Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
42 changes: 36 additions & 6 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,16 +39,45 @@ 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: Locate OpenSSL (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
foreach ($candidate in @(
"C:\Program Files\OpenSSL",
"C:\Program Files\OpenSSL-Win64",
"C:\OpenSSL-Win64"
)) {
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"
break
}
}
if (-not $env:OPENSSL_ROOT_DIR) {
choco install openssl --no-progress -y
"OPENSSL_ROOT_DIR=C:\Program Files\OpenSSL-Win64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
}
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
Expand Down
62 changes: 50 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,41 @@ jobs:
path: third_party/picotls
submodules: recursive

- name: Locate OpenSSL (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
foreach ($candidate in @(
"C:\Program Files\OpenSSL",
"C:\Program Files\OpenSSL-Win64",
"C:\OpenSSL-Win64"
)) {
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"
break
}
}
if (-not $env:OPENSSL_ROOT_DIR) {
choco install openssl --no-progress -y
"OPENSSL_ROOT_DIR=C:\Program Files\OpenSSL-Win64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
}
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 +99,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
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 requirement — OpenSSL**

picotls requires OpenSSL headers and libraries. On Windows you need to provide them separately and tell CMake where they are:

```powershell
# One-time: install OpenSSL (skip if already present)
choco install 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