Skip to content

Commit 0363136

Browse files
committed
Initial commit of codec2 0.2
0 parents  commit 0363136

137 files changed

Lines changed: 41112 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Keep the Docker build context small: only the Dockerfile and build-codec2.ps1
2+
# are needed inside the image.
3+
.git
4+
.github
5+
examples
6+
artifacts
7+
*.zip
8+
SHA256SUMS.txt
9+
configure-*.log
10+
build-*.log
11+
README.md
12+
.gitignore

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# This repository targets Windows. Keep CRLF line endings on checkout.
2+
* text=auto eol=crlf
3+
4+
# The build script is invoked as a file by CI/Docker; CRLF is fine for pwsh.
5+
*.ps1 text eol=crlf
6+
7+
# Anything binary that might land here stays untouched.
8+
*.zip binary
9+
*.dll binary
10+
*.lib binary
11+
*.pdb binary
12+
*.exe binary

.github/workflows/build-codec2.yml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
name: Build Codec2 (Windows)
2+
3+
# Builds Codec2 as a shared library (codec2.dll + codec2.lib) on a Windows runner
4+
# and uploads the headers + binaries as zip artifacts -- the same zips the Docker
5+
# image produces.
6+
#
7+
# Trigger manually (Actions tab -> "Build Codec2 (Windows)" -> Run workflow)
8+
# choosing the version, or push a tag like `codec2-v0.2` to build it and attach
9+
# the zips to a GitHub Release.
10+
11+
on:
12+
workflow_dispatch:
13+
inputs:
14+
codec2_version:
15+
description: 'Package/label version (vendored source is codec2 0.2; this just names the zips)'
16+
required: true
17+
default: '0.2'
18+
configs:
19+
description: 'Configurations to build (space-separated)'
20+
required: true
21+
default: 'Release Debug'
22+
platforms:
23+
description: 'Platforms to build (space-separated; x64-only by default, Win32 also supported)'
24+
required: true
25+
default: 'x64'
26+
push:
27+
tags:
28+
- 'codec2-v*' # e.g. push tag `codec2-v0.2`
29+
30+
jobs:
31+
build:
32+
runs-on: windows-2022
33+
timeout-minutes: 60
34+
permissions:
35+
contents: write # needed to attach zips to a Release on tag push
36+
steps:
37+
- name: Checkout builder
38+
uses: actions/checkout@v4
39+
40+
- name: Resolve build parameters
41+
id: p
42+
shell: pwsh
43+
run: |
44+
if ($env:GITHUB_EVENT_NAME -eq 'push') {
45+
# tag form: codec2-v0.2 -> version 0.2
46+
$ver = "$env:GITHUB_REF_NAME" -replace '^codec2-v', ''
47+
$cfg = 'Release Debug'
48+
$plat = 'x64'
49+
} else {
50+
$ver = '${{ inputs.codec2_version }}'
51+
$cfg = '${{ inputs.configs }}'
52+
$plat = '${{ inputs.platforms }}'
53+
}
54+
"codec2_version=$ver" >> $env:GITHUB_OUTPUT
55+
"configs=$cfg" >> $env:GITHUB_OUTPUT
56+
"platforms=$plat" >> $env:GITHUB_OUTPUT
57+
Write-Host "Building Codec2 $ver [$cfg] for [$plat]"
58+
59+
# windows-2022 ships Visual Studio 2022; confirm the C++ toolset (cl.exe) is
60+
# present via vswhere -- that's all build-codec2.ps1 needs (no CMake).
61+
- name: Verify toolchain
62+
shell: pwsh
63+
run: |
64+
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
65+
$vs = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | Select-Object -First 1
66+
if (-not $vs) { throw "No Visual Studio install with the C++ toolset (VC.Tools.x86.x64) was found." }
67+
Write-Host "VS install : $vs"
68+
69+
- name: Build Codec2 + package zips
70+
shell: pwsh
71+
env:
72+
CODEC2_VERSION: ${{ steps.p.outputs.codec2_version }}
73+
CONFIGS: ${{ steps.p.outputs.configs }}
74+
PLATFORMS: ${{ steps.p.outputs.platforms }}
75+
OUT_DIR: ${{ github.workspace }}\artifacts
76+
CODEC2_BUILD_ROOT: C:\cb
77+
run: .\build-codec2.ps1
78+
79+
- name: List artifacts
80+
shell: pwsh
81+
run: Get-ChildItem '${{ github.workspace }}\artifacts' | Format-Table Name, Length
82+
83+
- name: Upload zips
84+
uses: actions/upload-artifact@v4
85+
with:
86+
name: codec2-${{ steps.p.outputs.codec2_version }}
87+
path: |
88+
artifacts/*.zip
89+
artifacts/SHA256SUMS.txt
90+
artifacts/*.log
91+
if-no-files-found: error
92+
retention-days: 30
93+
94+
# On a tag push, also attach the zips to a GitHub Release for easy download.
95+
- name: Publish to Release
96+
if: github.event_name == 'push'
97+
uses: softprops/action-gh-release@v2
98+
with:
99+
files: |
100+
artifacts/*.zip
101+
artifacts/SHA256SUMS.txt

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Build outputs
2+
/artifacts/
3+
*.zip
4+
SHA256SUMS.txt
5+
configure-*.log
6+
build-*.log
7+
8+
# Codec2 source / build trees (when building natively in-tree)
9+
/cb/
10+
codec2-*.tar.gz
11+
build-*/
12+
install-*/
13+
14+
# OS / editor cruft
15+
Thumbs.db
16+
.DS_Store

Dockerfile

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# escape=`
2+
#
3+
# Builds Codec2 on Windows as a SHARED library (codec2.dll + codec2.lib import
4+
# library) with cl.exe from the Visual C++ toolchain, and packages the headers +
5+
# binaries into zip files -- the same zips the GitHub Actions workflow produces.
6+
#
7+
# The Codec2 source is VENDORED in this repo (.\source\codec2) and COPYied into
8+
# the image, so the build is fully offline -- no download, no CMake, no clang.
9+
# build-codec2.ps1 compiles the curated vocoder subset directly with cl /LD and
10+
# exports the API via libcodec2.def.
11+
#
12+
# Build the toolchain image once:
13+
# docker build -t libcodec2-packaging .
14+
#
15+
# Produce zips for a Codec2 release (writes to .\artifacts on the host):
16+
# docker run --rm --memory 4g `
17+
# -e CODEC2_VERSION=0.2 `
18+
# -v ${PWD}\artifacts:C:\artifacts `
19+
# libcodec2-packaging
20+
#
21+
# Requires Windows containers. The host must be able to run a Windows base image
22+
# of an equal-or-older build than the host (process isolation), otherwise run
23+
# with `--isolation=hyperv`.
24+
25+
ARG WINDOWS_BASE=mcr.microsoft.com/windows/servercore:ltsc2025
26+
FROM ${WINDOWS_BASE}
27+
28+
# The Visual Studio bootstrapper. aka.ms/vs/17/release installs the latest VS 2022
29+
# Build Tools.
30+
ARG VS_BOOTSTRAPPER_URL=https://aka.ms/vs/17/release/vs_buildtools.exe
31+
32+
SHELL ["powershell", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue';"]
33+
34+
# ---------------------------------------------------------------------------
35+
# Visual Studio 2022 Build Tools: the C++ workload (MSVC v143 + Windows SDK).
36+
# build-codec2.ps1 locates cl.exe via vswhere (installed by the bootstrapper)
37+
# and drives the build directly -- no CMake, no Chocolatey.
38+
# Exit code 3010 == success-but-reboot-required, which is fine in an image.
39+
# ---------------------------------------------------------------------------
40+
RUN Invoke-WebRequest -Uri $env:VS_BOOTSTRAPPER_URL -OutFile C:\vs_buildtools.exe; `
41+
Write-Host 'Installing Visual Studio Build Tools (this takes a while)...'; `
42+
$p = Start-Process -FilePath C:\vs_buildtools.exe -Wait -PassThru -ArgumentList `
43+
'--quiet','--wait','--norestart','--nocache', `
44+
'--installPath','C:\BuildTools', `
45+
'--add','Microsoft.VisualStudio.Workload.VCTools', `
46+
'--includeRecommended'; `
47+
if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) { throw "VS Build Tools install failed ($($p.ExitCode))" }; `
48+
Remove-Item C:\vs_buildtools.exe -Force
49+
50+
# ---------------------------------------------------------------------------
51+
# Build driver + vendored source.
52+
# ---------------------------------------------------------------------------
53+
COPY build-codec2.ps1 C:\build-codec2.ps1
54+
COPY source C:\source
55+
56+
# Defaults; override any of these with `docker run -e ...`.
57+
# CODEC2_VERSION is a label for the vendored source (which is codec2 0.2); it
58+
# names the output zips/folders and is NOT used to fetch anything.
59+
ENV CODEC2_VERSION=0.2 `
60+
CONFIGS="Release Debug" `
61+
PLATFORMS="x64" `
62+
PKG_PREFIX=libcodec2 `
63+
OUT_DIR=C:\artifacts `
64+
CODEC2_BUILD_ROOT=C:\cb
65+
66+
# NOTE: do NOT set `ENV PATH` here -- the Windows base image exports the variable
67+
# as `Path` (mixed case) and Docker's ${...} substitution is case-sensitive, so
68+
# `${PATH}` would expand to empty and wipe System32 from the path. The installer
69+
# registers its dirs in the machine PATH (which container processes inherit), and
70+
# build-codec2.ps1 invokes cl via vcvarsall at runtime.
71+
72+
ENTRYPOINT ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "C:\\build-codec2.ps1"]

README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# libcodec2-packaging
2+
3+
Builds **[Codec2](https://github.com/drowe67/codec2) as a shared library
4+
(`codec2.dll` + `codec2.lib` import library) on Windows** and packages the
5+
headers + binaries into zip files, via either GitHub Actions or a local Docker
6+
toolchain image.
7+
8+
The Codec2 source is **vendored in this repo** (`source/codec2`) and built
9+
directly with `cl.exe` — no download, no CMake, no clang. The build compiles the
10+
**vocoder subset** of `.c` files (the `codec2_*` encode/decode API) plus the
11+
pre-generated codebooks, and exports the API via `libcodec2.def`.
12+
13+
The vendored source is **codec2 0.2**. It predates codec2's move to C99
14+
variable-length arrays, so it compiles cleanly with MSVC `cl` — no Unix math lib,
15+
no clang.
16+
17+
## What it produces
18+
19+
For package version `0.2`, building `x64` × `Release Debug`:
20+
21+
```
22+
libcodec2-0.2-headers.zip libcodec2-0.2/include/codec2/{codec2.h, COPYING}
23+
libcodec2-0.2-binaries-x64-release.zip libcodec2-0.2/binaries/x64/Release/{codec2.dll, codec2.lib, codec2.pdb, COPYING}
24+
libcodec2-0.2-binaries-x64-debug.zip libcodec2-0.2/binaries/x64/Debug/{codec2.dll, codec2.lib, codec2.pdb, COPYING}
25+
SHA256SUMS.txt
26+
```
27+
28+
Each archive ships Codec2's `COPYING` (LGPL) next to its payload — not at the
29+
package root, since all zips extract into the same `libcodec2-0.2\` folder and a
30+
root-level copy would collide across them.
31+
32+
Zip *filenames* are lower-cased (`...-x64-release.zip`); the *paths inside* keep
33+
their original case (`binaries\x64\Release\...`).
34+
35+
> **x64 only** by default. Pass `PLATFORMS="x64 Win32"` to also build 32-bit.
36+
37+
## Repository layout
38+
39+
```
40+
.github/workflows/build-codec2.yml CI: build on a Windows runner, upload zip artifacts
41+
build-codec2.ps1 the build + package script (shared by CI and Docker)
42+
Dockerfile Windows-container toolchain image (for local/offline builds)
43+
source/codec2/ vendored codec2 0.2 source + libcodec2.def (the API export list)
44+
README.md
45+
```
46+
47+
## Building
48+
49+
### Option A — GitHub Actions (recommended)
50+
51+
The **Build Codec2 (Windows)** workflow runs on a `windows-2022` runner (which
52+
already has Visual Studio 2022 with the C++ toolset) and runs `build-codec2.ps1`.
53+
54+
- **Manually:** Actions tab → *Build Codec2 (Windows)***Run workflow**, then
55+
enter the version label (e.g. `0.2`), configs (`Release Debug`), and platforms (`x64`).
56+
- **By tag:** push a tag like `codec2-v0.2`. The workflow builds it and also
57+
attaches the zips to a GitHub Release.
58+
59+
### Option B — Local, via the Docker toolchain image
60+
61+
Requires Docker with **Windows containers** enabled.
62+
63+
```powershell
64+
# Build the toolchain image once (installs VS Build Tools).
65+
# This layer is large and slow; subsequent builds reuse it.
66+
docker build -t libcodec2-packaging .
67+
68+
# Produce zips (writes to .\artifacts on the host).
69+
# CONFIGS picks the configurations (default "Release Debug" -> builds BOTH);
70+
# PLATFORMS defaults to x64. See the parameters table below for every knob.
71+
docker run --rm --memory 4g `
72+
-e CODEC2_VERSION=0.2 `
73+
-e CONFIGS="Release Debug" `
74+
-v ${PWD}\artifacts:C:\artifacts `
75+
libcodec2-packaging
76+
```
77+
78+
cmd.exe: replace `${PWD}` with `%cd%`.
79+
80+
`CONFIGS` is space-separated; override it to build a single configuration:
81+
82+
```powershell
83+
# Debug only (omit -e CONFIGS entirely to get the default Release + Debug)
84+
docker run --rm --memory 4g -e CODEC2_VERSION=0.2 -e CONFIGS=Debug `
85+
-v ${PWD}\artifacts:C:\artifacts libcodec2-packaging
86+
```
87+
88+
The host must run a Windows base image of equal-or-older build for process
89+
isolation (the Dockerfile defaults to `servercore:ltsc2025`); otherwise pass
90+
`--build-arg WINDOWS_BASE=...:ltsc2022` or run with `--isolation=hyperv`.
91+
92+
### Option C — Local, native
93+
94+
If you already have **Visual Studio 2022 (C++ workload)** installed, just run the
95+
script directly (it locates `cl.exe` via `vswhere`):
96+
97+
```powershell
98+
$env:CODEC2_VERSION = '0.2'
99+
$env:CONFIGS = 'Release Debug'
100+
$env:OUT_DIR = "$PWD\artifacts"
101+
.\build-codec2.ps1
102+
```
103+
104+
### Build parameters (env vars)
105+
106+
| Var | Default | Notes |
107+
|---------------------|------------------|-------|
108+
| `CODEC2_VERSION` | `0.2` | Label for the vendored source; names the output zips/folders. Not used to fetch anything. |
109+
| `CONFIGS` | `Release Debug` | Space-separated: `Release`, `Debug`, or `Release Debug` (default builds both). |
110+
| `PLATFORMS` | `x64` | Space-separated. `x64` and/or `Win32`. |
111+
| `PKG_PREFIX` | `libcodec2` | Zip/folder name prefix. |
112+
| `OUT_DIR` | `C:\artifacts` | Where the zips are written (mount this in Docker). |
113+
| `CODEC2_BUILD_ROOT` | `C:\cb` | Scratch build dir (kept short to dodge MAX_PATH). |
114+
115+
## Consuming the zips
116+
117+
1. Extract `libcodec2-<ver>-binaries-x64-<cfg>.zip` and
118+
`libcodec2-<ver>-headers.zip` (they share the `libcodec2-<ver>\` root).
119+
2. Add `libcodec2-<ver>\include` (for `<codec2/codec2.h>`) and
120+
`…\include\codec2` (for `<codec2.h>`) to the include path.
121+
3. Link **`codec2.lib`** (the import library) and **ship `codec2.dll`** next to
122+
your binary — because Codec2 is dynamically linked, the DLL must ship.
123+
124+
## How the build works
125+
126+
`build-codec2.ps1`:
127+
128+
1. Copies the vendored `source\codec2` tree to a short scratch dir (keeps the repo
129+
clean) and sanity-checks that every source it compiles — plus `libcodec2.def`
130+
is present.
131+
2. Locates `cl.exe` via `vswhere` and, per platform × config, compiles the vocoder
132+
subset + pre-generated codebooks with `cl /LD` (`/MD` Release, `/MDd /Od /RTC1`
133+
Debug), exporting the API via `/DEF:libcodec2.def` and emitting the import lib
134+
with `/IMPLIB:codec2.lib`. This yields `codec2.dll` + `codec2.lib` + `codec2.pdb`.
135+
3. Packages the DLL/lib/PDB into the per-config binaries zip; packages `codec2.h`
136+
(and any local headers it `#include`s) into the headers zip; drops Codec2's
137+
`COPYING` license next to the payload in each zip; writes `SHA256SUMS.txt`.
138+
139+
## Notes & gotchas
140+
141+
- **Shared library.** This builds a DLL + import lib. The consumer must ship
142+
`codec2.dll` alongside its binary.
143+
- **`libcodec2.def` is the export list.** Only the symbols listed there are
144+
exported (and so end up in `codec2.lib`). If a consumer needs another `codec2_*`
145+
function, add it to `source\codec2\libcodec2.def` — a missing entry shows up as
146+
an `LNK2019` unresolved external in the consumer, not here.
147+
- **`LIBRARY codec2`** in the `.def` must match the output DLL name (`codec2.dll`),
148+
so the import lib records the right DLL to load at runtime.
149+
- **MSVC runtime.** Built with the dynamic CRT (`/MD`, `/MDd` for Debug); the
150+
consumer must use the same CRT.
151+
- **Offline & reproducible.** The source is vendored, so a build needs no network
152+
and any version label builds cleanly without a manual refresh.

0 commit comments

Comments
 (0)