|
| 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