Skip to content

Commit 5384b30

Browse files
committed
fix(linuxmusl-x64): disable LTO for SVT-AV1 on musl builds
SVT-AV1 enables LTO by default with GCC, but Alpine Linux (musl) lacks the GCC LTO plugin, causing link failures when consumers build against the published npm packages. - Add SVTAV1_CMAKE_OPTS variable with -DSVT_AV1_LTO=OFF for musl - Update shared svt-av1.mk recipe to consume platform-specific CMake opts - Include openspec change proposal documenting the fix
1 parent 97bb238 commit 5384b30

6 files changed

Lines changed: 186 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Design: Disable LTO for SVT-AV1 on musl Builds
2+
3+
## Context
4+
5+
SVT-AV1 v2.3.0 enables LTO by default when built with GCC (via `SVT_AV1_LTO` CMake option). This optimization embeds GCC-specific bytecode into the static library. When consumers link against this library, they need a matching GCC LTO plugin version.
6+
7+
Alpine Linux (musl libc) does not ship the GCC LTO plugin by default, and even when installed, version mismatches between build-time and link-time GCC cause failures.
8+
9+
**Constraints:**
10+
- Must not impact other platforms (darwin, linux-glibc)
11+
- Must preserve SVT-AV1 performance on platforms where LTO works
12+
- Must be maintainable alongside existing platform configuration pattern
13+
14+
## Goals / Non-Goals
15+
16+
**Goals:**
17+
- Enable successful musl builds without requiring LTO plugin
18+
- Maintain single shared SVT-AV1 recipe
19+
- Follow existing platform configuration patterns
20+
21+
**Non-Goals:**
22+
- Disable LTO globally (other codecs/platforms unaffected)
23+
- Add new build system abstractions
24+
25+
## Decisions
26+
27+
### Decision 1: Use codec-specific CMake variable
28+
29+
**What:** Add `SVTAV1_CMAKE_OPTS` variable that platforms can optionally define.
30+
31+
**Why:**
32+
- Follows existing pattern (e.g., `LIBVPX_TARGET`, `X264_HOST`, `AOM_TARGET_CPU`)
33+
- Minimal change to shared recipe
34+
- Platform-specific without creating recipe duplication
35+
36+
**Alternatives considered:**
37+
1. **Global `CMAKE_OPTS` modification** - Too broad, affects all CMake codecs
38+
2. **Platform-specific svt-av1.mk** - Creates duplication, violates DRY
39+
3. **Conditional in shared recipe** - Adds `ifeq` complexity to shared code
40+
41+
### Decision 2: Default to empty (no-op)
42+
43+
**What:** `SVTAV1_CMAKE_OPTS ?=` defaults to empty in shared recipe.
44+
45+
**Why:**
46+
- Platforms that don't define it get default SVT-AV1 behavior (LTO enabled)
47+
- Only musl platform explicitly disables LTO
48+
- No impact on darwin/linux-glibc builds
49+
50+
## Implementation
51+
52+
### File: `platforms/linuxmusl-x64/config.mk`
53+
54+
Add after codec-specific overrides section:
55+
```makefile
56+
# SVT-AV1: Disable LTO on musl (GCC LTO plugin not available by default)
57+
SVTAV1_CMAKE_OPTS := -DSVT_AV1_LTO=OFF
58+
```
59+
60+
### File: `shared/codecs/bsd/svt-av1.mk`
61+
62+
Modify cmake invocation:
63+
```makefile
64+
# Default: empty (LTO enabled on most platforms)
65+
SVTAV1_CMAKE_OPTS ?=
66+
67+
svt-av1.stamp:
68+
...
69+
cd $(SVTAV1_BUILD) && \
70+
cmake $(SVTAV1_SRC) \
71+
$(CMAKE_OPTS) \
72+
$(SVTAV1_CMAKE_OPTS) \
73+
-DBUILD_SHARED_LIBS=OFF \
74+
...
75+
```
76+
77+
## Risks / Trade-offs
78+
79+
| Risk | Impact | Mitigation |
80+
|------|--------|------------|
81+
| Slight performance regression on musl | Low - LTO gains are ~1-5% for encoding | Acceptable for build compatibility |
82+
| Pattern proliferation | Low - Only needed for SVT-AV1 | Document in CLAUDE.md if more codecs need this |
83+
84+
## Migration Plan
85+
86+
No migration needed - this is a build system fix that doesn't affect API or package structure.
87+
88+
**Rollback:** Remove `SVTAV1_CMAKE_OPTS` from config.mk and revert svt-av1.mk changes.
89+
90+
## Open Questions
91+
92+
None - implementation is straightforward.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Change: Disable LTO for SVT-AV1 on musl Builds
2+
3+
## Why
4+
5+
SVT-AV1 enables Link-Time Optimization (LTO) by default when compiled with GCC. On Alpine Linux (musl), linking FFmpeg against SVT-AV1 libraries built with LTO fails because musl's GCC toolchain lacks the LTO plugin (`liblto_plugin.so`). This causes CI failures for the `linuxmusl-x64` platform when consumers attempt to link against the published npm packages.
6+
7+
Error symptom:
8+
```
9+
lto1: fatal error: bytecode stream in file 'libSvtAv1Enc.a' generated with LTO version X.Y instead of the expected X.Z
10+
```
11+
12+
## What Changes
13+
14+
- Add `-DSVT_AV1_LTO=OFF` to SVT-AV1 CMake configuration specifically for musl builds
15+
- Introduce platform-specific CMake override mechanism (`CMAKE_CODEC_OPTS`) for codec-specific flags
16+
17+
## Impact
18+
19+
- **Affected specs**: None (build system configuration, no spec changes)
20+
- **Affected code**:
21+
- `platforms/linuxmusl-x64/config.mk` - Add SVT-AV1 LTO disable flag
22+
- `shared/codecs/bsd/svt-av1.mk` - Consume platform-specific CMake options
23+
24+
## Scope
25+
26+
- **Platform**: `linuxmusl-x64` only (other platforms are unaffected)
27+
- **Codec**: SVT-AV1 only
28+
- **License tiers**: Both `free` and `non-free` (SVT-AV1 is in BSD tier)
29+
30+
## Problems Solved
31+
32+
1. **CI failures**: `linuxmusl-x64` builds will complete successfully
33+
2. **Consumer linking**: npm package consumers on Alpine Linux can link against the libraries without LTO plugin requirements
34+
3. **Compatibility**: Ensures binaries work across GCC versions without strict LTO version matching
35+
36+
## Alternatives Considered
37+
38+
1. **Install GCC LTO plugin on Alpine** - Rejected: Fragile, requires matching GCC versions between build and link time
39+
2. **Disable LTO globally via CFLAGS** - Rejected: Overly broad, may impact performance on other codecs
40+
3. **Platform-specific SVT-AV1 recipe** - Rejected: Creates duplication, harder to maintain
41+
42+
## Release
43+
44+
Publish as `@pproenca/webcodecs-ffmpeg-linux-x64-musl@0.1.5` after verification.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## ADDED Requirements
2+
3+
### Requirement: SVT-AV1 LTO Configuration
4+
5+
The build system SHALL support platform-specific LTO configuration for SVT-AV1 via the `SVTAV1_CMAKE_OPTS` variable.
6+
7+
#### Scenario: musl platform disables LTO
8+
- **WHEN** building SVT-AV1 on `linuxmusl-x64` platform
9+
- **THEN** LTO SHALL be disabled via `-DSVT_AV1_LTO=OFF`
10+
- **AND** the resulting `libSvtAv1Enc.a` SHALL NOT contain LTO bytecode
11+
12+
#### Scenario: Other platforms retain default LTO behavior
13+
- **WHEN** building SVT-AV1 on non-musl platforms (darwin-arm64, darwin-x64, linux-arm64, linux-x64)
14+
- **THEN** `SVTAV1_CMAKE_OPTS` SHALL be empty by default
15+
- **AND** SVT-AV1's default LTO behavior SHALL be preserved
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Tasks: Disable LTO for SVT-AV1 on musl Builds
2+
3+
## 1. Implementation
4+
5+
- [x] 1.1 Add `SVTAV1_CMAKE_OPTS` variable to `platforms/linuxmusl-x64/config.mk` with `-DSVT_AV1_LTO=OFF`
6+
- [x] 1.2 Update `shared/codecs/bsd/svt-av1.mk` to include `$(SVTAV1_CMAKE_OPTS)` in cmake invocation
7+
- [x] 1.3 Add comment in config.mk explaining why LTO is disabled for musl
8+
9+
## 2. Verification
10+
11+
- [ ] 2.1 Build SVT-AV1 locally on musl container to confirm LTO is disabled
12+
- [ ] 2.2 Verify `libSvtAv1Enc.a` does not contain LTO bytecode (inspect with `file` or `nm`)
13+
- [ ] 2.3 Confirm FFmpeg links successfully against the rebuilt library
14+
15+
## 3. CI Validation
16+
17+
- [ ] 3.1 Push changes to trigger CI build for `linuxmusl-x64`
18+
- [ ] 3.2 Verify both `free` and `non-free` tiers build successfully
19+
- [ ] 3.3 Confirm existing platforms (darwin-arm64, darwin-x64, linux-arm64, linux-x64) are unaffected
20+
21+
## 4. Release
22+
23+
- [ ] 4.1 Run `./scripts/bump-version.sh patch` to bump to 0.1.5
24+
- [ ] 4.2 Push commit and tag: `git push origin master v0.1.5`
25+
- [ ] 4.3 Trigger release workflow with tag `v0.1.5`
26+
- [ ] 4.4 Verify npm packages published successfully

platforms/linuxmusl-x64/config.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ AOM_TARGET_CPU := x86_64
8787
# Architecture pattern for file command verification
8888
ARCH_VERIFY_PATTERN := x86-64
8989

90+
# SVT-AV1: Disable LTO on musl (GCC LTO plugin not available by default,
91+
# and version mismatches between build-time and link-time GCC cause failures)
92+
SVTAV1_CMAKE_OPTS := -DSVT_AV1_LTO=OFF
93+
9094
# FFmpeg extra libraries for linking
9195
# musl doesn't need -ldl (dlopen is in libc)
9296
FFMPEG_EXTRA_LIBS := -lpthread -lm -lstdc++

shared/codecs/bsd/svt-av1.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
SVTAV1_SRC := $(SOURCES_DIR)/SVT-AV1-$(SVTAV1_VERSION)
99
SVTAV1_BUILD := $(SVTAV1_SRC)/build
1010

11+
# Platform-specific CMake options (default: empty, LTO enabled)
12+
# Override in platform config.mk to disable LTO on musl
13+
SVTAV1_CMAKE_OPTS ?=
14+
1115
svt-av1.stamp:
1216
$(call log_info,Building SVT-AV1 $(SVTAV1_VERSION)...)
1317
@mkdir -p $(SOURCES_DIR) $(STAMPS_DIR)
@@ -16,6 +20,7 @@ svt-av1.stamp:
1620
cd $(SVTAV1_BUILD) && \
1721
cmake $(SVTAV1_SRC) \
1822
$(CMAKE_OPTS) \
23+
$(SVTAV1_CMAKE_OPTS) \
1924
-DBUILD_SHARED_LIBS=OFF \
2025
-DBUILD_APPS=OFF \
2126
-DBUILD_DEC=ON \

0 commit comments

Comments
 (0)