Skip to content

Commit 5839cc8

Browse files
committed
ci: build TagLib 2.2 from source and compile Mixxx against it
Focal ships TagLib 1.11.1 which has no Matroska support, so the native MKV/WebM metadata path in metadatasourcetaglib.cpp is compiled out. This workflow builds TagLib 2.2 from source into /opt/taglib/2.2 and points PKG_CONFIG_PATH at it, then compiles Mixxx against it and verifies via ldd that the binary links the TagLib 2.2 shared library. Manual trigger or on push to this test branch.
1 parent 20aaf18 commit 5839cc8

1 file changed

Lines changed: 289 additions & 0 deletions

File tree

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow
2+
name: Ubuntu 20.04 Focal build with TagLib 2.2 (Qt 6 from artifact)
3+
4+
# Manual trigger, and automatic on pushes to the mkv/webm taglib-2.2 test branch.
5+
on:
6+
workflow_dispatch:
7+
push:
8+
branches:
9+
- mkv-webm-taglib22-ci
10+
11+
permissions:
12+
contents: read
13+
actions: read
14+
15+
env:
16+
QT_VERSION: 6.10.3
17+
QT_PREFIX: /opt/qt/6.10.3
18+
TAGLIB_VERSION: 2.2
19+
TAGLIB_PREFIX: /opt/taglib/2.2
20+
21+
jobs:
22+
build:
23+
name: Ubuntu 20.04 (Focal) compile against TagLib 2.2
24+
runs-on: ubuntu-24.04
25+
container: ubuntu:20.04
26+
27+
env:
28+
DEBIAN_FRONTEND: noninteractive
29+
TZ: Etc/UTC
30+
CMAKE_VERSION: 3.31.8
31+
32+
steps:
33+
- name: Check out repository
34+
uses: actions/checkout@v7
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Prepare Focal build environment
39+
shell: bash
40+
run: |
41+
set -o pipefail
42+
mkdir -p logs build
43+
{
44+
echo '=== OS ==='
45+
cat /etc/os-release
46+
echo
47+
echo '=== Kernel ==='
48+
uname -a
49+
echo
50+
echo '=== CPU ==='
51+
nproc
52+
echo
53+
echo '=== APT sources ==='
54+
grep -RhsE '^[[:space:]]*deb([[:space:]]|$)' /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null || true
55+
} | tee logs/00-environment.log
56+
57+
apt-get update 2>&1 | tee logs/01-apt-update.log
58+
apt-get install -y --no-install-recommends \
59+
bash ca-certificates git wget curl xz-utils file pkg-config unzip \
60+
ninja-build build-essential python3 python3-pip sudo gdb \
61+
zlib1g-dev \
62+
2>&1 | tee logs/02-base-packages.log
63+
64+
- name: Install CMake
65+
shell: bash
66+
run: |
67+
set -o pipefail
68+
wget -qO- "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz" \
69+
| tar -xz -C /opt
70+
ln -sf "/opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/cmake" /usr/local/bin/cmake
71+
ln -sf "/opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/ctest" /usr/local/bin/ctest
72+
cmake --version 2>&1 | tee logs/03-cmake-version.log
73+
74+
- name: Install Mixxx build dependencies (Focal-compatible, no Qt)
75+
shell: bash
76+
run: |
77+
set -o pipefail
78+
export DEBIAN_FRONTEND=noninteractive
79+
cp tools/debian_buildenv.sh /tmp/debian_buildenv-focal.sh
80+
apt-get install -y --no-install-recommends software-properties-common 2>&1 | tee logs/04-ppatools.log
81+
add-apt-repository -y ppa:ubuntu-toolchain-r/test 2>&1 | tee logs/04-ppa.log
82+
apt-get update 2>&1 | tee logs/04-ppa-update.log
83+
apt-get install -y --no-install-recommends gcc-12 g++-12 2>&1 | tee logs/04-focal-toolchain.log
84+
apt-get install -y --no-install-recommends libxkbcommon-dev libxkbcommon-x11-dev 2>&1 | tee logs/04-xkbcommon.log
85+
apt-get install -y --no-install-recommends libdbus-1-3 2>&1 | tee logs/04-dbus.log
86+
sed -i \
87+
-e '/libpipewire-0.3-dev/d' \
88+
-e '/libspa-0.2-dev/d' \
89+
-e '/libqt6/d' \
90+
-e '/^ *qt6-/d' \
91+
-e '/^ *qtkeychain-qt6-dev/d' \
92+
-e '/^ *qml6-/d' \
93+
-e '/qt6-shadertools-dev/d' \
94+
-e '/qt6-5compat-dev/d' \
95+
-e 's/sudo apt-get/apt-get/g' \
96+
/tmp/debian_buildenv-focal.sh
97+
chmod +x /tmp/debian_buildenv-focal.sh
98+
/tmp/debian_buildenv-focal.sh setup 2>&1 | tee logs/04-mixxx-buildenv.log
99+
# Focal ships TagLib 1.11.1 (libtag1-dev). It stays installed but the
100+
# configure step puts /opt/taglib/2.2 first in PKG_CONFIG_PATH, so
101+
# Mixxx resolves TagLib 2.2 from the source build below.
102+
103+
- name: Build hidapi 0.14.0 (Focal ships 0.9.0)
104+
shell: bash
105+
run: |
106+
set -o pipefail
107+
wget -q "https://github.com/libusb/hidapi/archive/refs/tags/hidapi-0.14.0.tar.gz" -O /tmp/hidapi.tar.gz
108+
tar -xzf /tmp/hidapi.tar.gz -C /tmp
109+
cmake -S /tmp/hidapi-hidapi-0.14.0 -B /tmp/hidapi-build \
110+
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DHIDAPI_BUILD_HIDTEST=OFF \
111+
2>&1 | tee logs/05-hidapi-configure.log
112+
cmake --build /tmp/hidapi-build -j"$(nproc)" 2>&1 | tee logs/05-hidapi-build.log
113+
cmake --install /tmp/hidapi-build 2>&1 | tee logs/05-hidapi-install.log
114+
ldconfig
115+
nm -D /usr/local/lib/libhidapi-hidraw.so.0 | grep -q ' hid_get_report_descriptor$'
116+
117+
- name: Build TagLib ${TAGLIB_VERSION} from source (native Matroska/WebM)
118+
shell: bash
119+
run: |
120+
set -o pipefail
121+
wget -q "https://github.com/taglib/taglib/releases/download/v${TAGLIB_VERSION}/taglib-${TAGLIB_VERSION}.tar.gz" -O /tmp/taglib.tar.gz
122+
tar -xzf /tmp/taglib.tar.gz -C /tmp
123+
cmake -S "/tmp/taglib-${TAGLIB_VERSION}" -B /tmp/taglib-build \
124+
-DCMAKE_BUILD_TYPE=Release \
125+
-DCMAKE_INSTALL_PREFIX="${TAGLIB_PREFIX}" \
126+
-DBUILD_SHARED_LIBS=ON \
127+
-DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF \
128+
2>&1 | tee logs/06-taglib-configure.log
129+
cmake --build /tmp/taglib-build -j"$(nproc)" 2>&1 | tee logs/06-taglib-build.log
130+
cmake --install /tmp/taglib-build 2>&1 | tee logs/06-taglib-install.log
131+
ldconfig
132+
echo '=== TagLib version + Matroska module ==='
133+
PKG_CONFIG_PATH="${TAGLIB_PREFIX}/lib/pkgconfig" pkg-config --modversion taglib
134+
test -f "${TAGLIB_PREFIX}/include/taglib/matroskafile.h" && echo "matroskafile.h present"
135+
grep -E 'TAGLIB_(MAJOR|MINOR|PATCH)_VERSION' "${TAGLIB_PREFIX}/include/taglib/taglib.h"
136+
grep -q 'TAGLIB_WITH_MATROSKA 1' "${TAGLIB_PREFIX}/include/taglib/taglib_config.h" && echo "TAGLIB_WITH_MATROSKA=1"
137+
138+
- name: Find Qt artifact build
139+
id: find-qt
140+
uses: actions/github-script@v9
141+
with:
142+
script: |
143+
const { data } = await github.rest.actions.listWorkflowRuns({
144+
owner: context.repo.owner,
145+
repo: context.repo.repo,
146+
workflow_id: 'qt6-focal.yml',
147+
status: 'success',
148+
per_page: 1,
149+
});
150+
if (data.total_count === 0) {
151+
core.setFailed('No successful qt6-focal.yml run found; run that workflow first.');
152+
}
153+
const run = data.workflow_runs[0];
154+
core.setOutput('run_id', String(run.id));
155+
console.log(`Using Qt build run ${run.id}`);
156+
157+
- name: Download Qt artifact
158+
id: download-qt
159+
uses: actions/github-script@v9
160+
env:
161+
RUN_ID: ${{ steps.find-qt.outputs.run_id }}
162+
with:
163+
script: |
164+
const fs = require('fs');
165+
const dir = '/tmp/qt-artifact';
166+
fs.mkdirSync(dir, { recursive: true });
167+
const artifactName = `qt-${process.env.QT_VERSION}-ubuntu20.04`;
168+
const { data: list } = await github.rest.actions.listWorkflowRunArtifacts({
169+
owner: context.repo.owner,
170+
repo: context.repo.repo,
171+
run_id: Number(process.env.RUN_ID),
172+
});
173+
const artifact = list.artifacts.find(a => a.name === artifactName);
174+
if (!artifact) {
175+
core.setFailed(`Artifact ${artifactName} not found on run ${process.env.RUN_ID}`);
176+
return;
177+
}
178+
const { data } = await github.rest.actions.downloadArtifact({
179+
owner: context.repo.owner,
180+
repo: context.repo.repo,
181+
artifact_id: artifact.id,
182+
archive_format: 'zip',
183+
});
184+
fs.writeFileSync(`${dir}/qt.zip`, Buffer.from(data));
185+
console.log(`Downloaded ${artifactName} (${artifact.size_in_bytes} bytes) from run ${process.env.RUN_ID}`);
186+
187+
- name: Install Qt artifact
188+
shell: bash
189+
run: |
190+
set -o pipefail
191+
cd /tmp/qt-artifact
192+
unzip -o qt.zip
193+
expected=$(awk '{print $1}' "qt-${QT_VERSION}-ubuntu20.04.tar.xz.sha256")
194+
actual=$(sha256sum "qt-${QT_VERSION}-ubuntu20.04.tar.xz" | awk '{print $1}')
195+
echo "expected: ${expected}"
196+
echo "actual: ${actual}"
197+
test "${expected}" = "${actual}" || { echo "Qt artifact checksum mismatch" >&2; exit 1; }
198+
mkdir -p /opt/qt
199+
tar -C /opt/qt -xJf "qt-${QT_VERSION}-ubuntu20.04.tar.xz" 2>&1 | tee "${GITHUB_WORKSPACE}/logs/05-qt-install.log"
200+
"${QT_PREFIX}/bin/qmake" --version 2>&1 | tee -a "${GITHUB_WORKSPACE}/logs/05-qt-install.log"
201+
202+
- name: Configure (Release, against TagLib ${TAGLIB_VERSION})
203+
shell: bash
204+
env:
205+
CMAKE_PREFIX_PATH: /opt/qt/6.10.3:/usr/local:${{ env.TAGLIB_PREFIX }}
206+
PKG_CONFIG_PATH: ${{ env.TAGLIB_PREFIX }}/lib/pkgconfig
207+
LD_LIBRARY_PATH: /opt/qt/6.10.3/lib:/usr/local/lib:${{ env.TAGLIB_PREFIX }}/lib
208+
CC: gcc-12
209+
CXX: g++-12
210+
run: |
211+
set -o pipefail
212+
export PATH=/opt/qt/6.10.3/bin:$PATH
213+
cmake \
214+
-S . -B build \
215+
-DCMAKE_BUILD_TYPE=Release \
216+
-DQT6=ON \
217+
-DQML=ON \
218+
-DBULK=ON \
219+
-DFFMPEG=ON \
220+
-DLOCALECOMPARE=ON \
221+
-DMAD=ON \
222+
-DMODPLUG=ON \
223+
-DWAVPACK=ON \
224+
-DBUILD_BENCH=OFF \
225+
-DQTKEYCHAIN=OFF \
226+
-DINSTALL_USER_UDEV_RULES=OFF \
227+
2>&1 | tee logs/07-cmake-configure.log
228+
echo '=== TagLib resolved by Mixxx ==='
229+
grep -iE 'TagLib' build/CMakeCache.txt || true
230+
grep -E 'Found TagLib|suitable version "2\.2"' logs/07-cmake-configure.log || true
231+
232+
- name: Build (Release)
233+
shell: bash
234+
env:
235+
CMAKE_PREFIX_PATH: /opt/qt/6.10.3:/usr/local:${{ env.TAGLIB_PREFIX }}
236+
PKG_CONFIG_PATH: ${{ env.TAGLIB_PREFIX }}/lib/pkgconfig
237+
LD_LIBRARY_PATH: /opt/qt/6.10.3/lib:/usr/local/lib:${{ env.TAGLIB_PREFIX }}/lib
238+
CC: gcc-12
239+
CXX: g++-12
240+
run: |
241+
set -o pipefail
242+
export PATH=/opt/qt/6.10.3/bin:$PATH
243+
cmake --build build -j"$(nproc)" 2>&1 | tee logs/08-cmake-build.log
244+
245+
- name: Verify linked TagLib version
246+
shell: bash
247+
run: |
248+
set -o pipefail
249+
lib=$(ldd build/mixxx 2>/dev/null | awk '/libtag\.so/{print $3}' | head -1)
250+
echo "libtag resolved to: ${lib}"
251+
ldd build/mixxx 2>&1 | grep -i taglib | tee logs/09-taglib-linkage.log
252+
case "${lib}" in
253+
${TAGLIB_PREFIX}/*)
254+
echo "OK: mixxx links TagLib ${TAGLIB_VERSION} from ${TAGLIB_PREFIX}"
255+
;;
256+
*)
257+
echo "FAIL: libtag is not from ${TAGLIB_PREFIX}" >&2
258+
exit 1
259+
;;
260+
esac
261+
262+
- name: Collect diagnostics
263+
if: always()
264+
shell: bash
265+
run: |
266+
set -o pipefail
267+
{
268+
echo '=== Git status ==='
269+
git status --short 2>/dev/null || true
270+
echo
271+
echo '=== CMake cache ==='
272+
grep -E '^(CMAKE_(BUILD_TYPE|CXX_COMPILER|C_COMPILER):|QT6:|FFMPEG:|TagLib|PC_TagLib)' build/CMakeCache.txt 2>/dev/null || true
273+
echo
274+
echo '=== Version strings ==='
275+
grep -E 'MIXXX_VERSION|VERSION_PRERELEASE' CMakeLists.txt | head -5
276+
echo
277+
echo '=== TagLib install ==='
278+
ls -la "${TAGLIB_PREFIX}/lib/" 2>/dev/null | grep -i 'libtag' || true
279+
ls "${TAGLIB_PREFIX}/include/taglib/" 2>/dev/null | grep -i matroska || true
280+
} | tee logs/99-diagnostics.log
281+
282+
- name: Upload logs
283+
if: always()
284+
uses: actions/upload-artifact@v4
285+
with:
286+
name: ubuntu-20.04-qt6-taglib22-build-${{ github.run_number }}
287+
path: logs/
288+
if-no-files-found: warn
289+
retention-days: 14

0 commit comments

Comments
 (0)