Ubuntu 20.04 Focal build with TagLib 2.2 (Qt 6 from artifact) #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # yaml-language-server: $schema=https://json.schemastore.org/github-workflow | |
| name: Ubuntu 20.04 Focal build with TagLib 2.2 / 1.11 (Qt 6 from artifact) | |
| # Manual trigger, and automatic on pushes to the mkv/webm taglib-2.2 test branch. | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - mkv-webm-taglib22-ci | |
| permissions: | |
| contents: read | |
| actions: read | |
| env: | |
| QT_VERSION: 6.10.3 | |
| QT_PREFIX: /opt/qt/6.10.3 | |
| jobs: | |
| build: | |
| name: Ubuntu 20.04 (Focal) compile against TagLib ${{ matrix.taglib_version }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - taglib_version: "2.2" | |
| taglib_prefix: /opt/taglib/2.2 | |
| taglib_pkgconfig: /opt/taglib/2.2/lib/pkgconfig | |
| build_taglib_from_source: true | |
| artifact_tag: taglib22 | |
| - taglib_version: "1.11" | |
| taglib_prefix: /usr | |
| taglib_pkgconfig: /usr/local/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig | |
| build_taglib_from_source: false | |
| artifact_tag: taglib111 | |
| runs-on: ubuntu-24.04 | |
| container: ubuntu:20.04 | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| TZ: Etc/UTC | |
| CMAKE_VERSION: 3.31.8 | |
| TAGLIB_VERSION: ${{ matrix.taglib_version }} | |
| TAGLIB_PREFIX: ${{ matrix.taglib_prefix }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Prepare Focal build environment | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| mkdir -p logs build | |
| { | |
| echo '=== OS ===' | |
| cat /etc/os-release | |
| echo | |
| echo '=== Kernel ===' | |
| uname -a | |
| echo | |
| echo '=== CPU ===' | |
| nproc | |
| echo | |
| echo '=== APT sources ===' | |
| grep -RhsE '^[[:space:]]*deb([[:space:]]|$)' /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null || true | |
| } | tee logs/00-environment.log | |
| apt-get update 2>&1 | tee logs/01-apt-update.log | |
| apt-get install -y --no-install-recommends \ | |
| bash ca-certificates git wget curl xz-utils file pkg-config unzip \ | |
| ninja-build build-essential python3 python3-pip sudo gdb \ | |
| zlib1g-dev \ | |
| 2>&1 | tee logs/02-base-packages.log | |
| - name: Install CMake | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| wget -qO- "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz" \ | |
| | tar -xz -C /opt | |
| ln -sf "/opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/cmake" /usr/local/bin/cmake | |
| ln -sf "/opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/ctest" /usr/local/bin/ctest | |
| cmake --version 2>&1 | tee logs/03-cmake-version.log | |
| - name: Install Mixxx build dependencies (Focal-compatible, no Qt) | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| export DEBIAN_FRONTEND=noninteractive | |
| cp tools/debian_buildenv.sh /tmp/debian_buildenv-focal.sh | |
| apt-get install -y --no-install-recommends software-properties-common 2>&1 | tee logs/04-ppatools.log | |
| add-apt-repository -y ppa:ubuntu-toolchain-r/test 2>&1 | tee logs/04-ppa.log | |
| apt-get update 2>&1 | tee logs/04-ppa-update.log | |
| apt-get install -y --no-install-recommends gcc-12 g++-12 2>&1 | tee logs/04-focal-toolchain.log | |
| apt-get install -y --no-install-recommends libxkbcommon-dev libxkbcommon-x11-dev 2>&1 | tee logs/04-xkbcommon.log | |
| apt-get install -y --no-install-recommends libdbus-1-3 2>&1 | tee logs/04-dbus.log | |
| sed -i \ | |
| -e '/libpipewire-0.3-dev/d' \ | |
| -e '/libspa-0.2-dev/d' \ | |
| -e '/libqt6/d' \ | |
| -e '/^ *qt6-/d' \ | |
| -e '/^ *qtkeychain-qt6-dev/d' \ | |
| -e '/^ *qml6-/d' \ | |
| -e '/qt6-shadertools-dev/d' \ | |
| -e '/qt6-5compat-dev/d' \ | |
| -e 's/sudo apt-get/apt-get/g' \ | |
| /tmp/debian_buildenv-focal.sh | |
| chmod +x /tmp/debian_buildenv-focal.sh | |
| /tmp/debian_buildenv-focal.sh setup 2>&1 | tee logs/04-mixxx-buildenv.log | |
| # Focal ships TagLib 1.11.1 (libtag1-dev), which has no Matroska | |
| # support. The 2.2 leg overrides it by putting /opt/taglib/2.2 first | |
| # in PKG_CONFIG_PATH; the 1.11 leg uses the system package and thus | |
| # exercises the FFmpeg metadata fallback path. | |
| # The 1.11 leg's PKG_CONFIG_PATH puts /usr/local/lib/pkgconfig first | |
| # so the freshly built hidapi 0.14.0 .pc wins over the apt one | |
| # (0.9.0) that /usr/lib/x86_64-linux-gnu/pkgconfig would otherwise | |
| # shadow; /usr/local has no taglib.pc, so system TagLib 1.11 still | |
| # resolves from the second entry. | |
| - name: Build hidapi 0.14.0 (Focal ships 0.9.0) | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| wget -q "https://github.com/libusb/hidapi/archive/refs/tags/hidapi-0.14.0.tar.gz" -O /tmp/hidapi.tar.gz | |
| tar -xzf /tmp/hidapi.tar.gz -C /tmp | |
| cmake -S /tmp/hidapi-hidapi-0.14.0 -B /tmp/hidapi-build \ | |
| -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DHIDAPI_BUILD_HIDTEST=OFF \ | |
| 2>&1 | tee logs/05-hidapi-configure.log | |
| cmake --build /tmp/hidapi-build -j"$(nproc)" 2>&1 | tee logs/05-hidapi-build.log | |
| cmake --install /tmp/hidapi-build 2>&1 | tee logs/05-hidapi-install.log | |
| ldconfig | |
| nm -D /usr/local/lib/libhidapi-hidraw.so.0 | grep -q ' hid_get_report_descriptor$' | |
| - name: Build TagLib ${TAGLIB_VERSION} from source (native Matroska/WebM) | |
| if: matrix.build_taglib_from_source | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| wget -q "https://github.com/taglib/taglib/releases/download/v${TAGLIB_VERSION}/taglib-${TAGLIB_VERSION}.tar.gz" -O /tmp/taglib.tar.gz | |
| tar -xzf /tmp/taglib.tar.gz -C /tmp | |
| cmake -S "/tmp/taglib-${TAGLIB_VERSION}" -B /tmp/taglib-build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_INSTALL_PREFIX="${TAGLIB_PREFIX}" \ | |
| -DBUILD_SHARED_LIBS=ON \ | |
| -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF \ | |
| 2>&1 | tee logs/06-taglib-configure.log | |
| cmake --build /tmp/taglib-build -j"$(nproc)" 2>&1 | tee logs/06-taglib-build.log | |
| cmake --install /tmp/taglib-build 2>&1 | tee logs/06-taglib-install.log | |
| ldconfig | |
| echo '=== TagLib version + Matroska module ===' | |
| PKG_CONFIG_PATH="${TAGLIB_PREFIX}/lib/pkgconfig" pkg-config --modversion taglib | |
| test -f "${TAGLIB_PREFIX}/include/taglib/matroskafile.h" && echo "matroskafile.h present" | |
| grep -E 'TAGLIB_(MAJOR|MINOR|PATCH)_VERSION' "${TAGLIB_PREFIX}/include/taglib/taglib.h" | |
| grep -q 'TAGLIB_WITH_MATROSKA 1' "${TAGLIB_PREFIX}/include/taglib/taglib_config.h" && echo "TAGLIB_WITH_MATROSKA=1" | |
| - name: Find Qt artifact build | |
| id: find-qt | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const { data } = await github.rest.actions.listWorkflowRuns({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'qt6-focal.yml', | |
| status: 'success', | |
| per_page: 1, | |
| }); | |
| if (data.total_count === 0) { | |
| core.setFailed('No successful qt6-focal.yml run found; run that workflow first.'); | |
| } | |
| const run = data.workflow_runs[0]; | |
| core.setOutput('run_id', String(run.id)); | |
| console.log(`Using Qt build run ${run.id}`); | |
| - name: Download Qt artifact | |
| id: download-qt | |
| uses: actions/github-script@v9 | |
| env: | |
| RUN_ID: ${{ steps.find-qt.outputs.run_id }} | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const dir = '/tmp/qt-artifact'; | |
| fs.mkdirSync(dir, { recursive: true }); | |
| const artifactName = `qt-${process.env.QT_VERSION}-ubuntu20.04`; | |
| const { data: list } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: Number(process.env.RUN_ID), | |
| }); | |
| const artifact = list.artifacts.find(a => a.name === artifactName); | |
| if (!artifact) { | |
| core.setFailed(`Artifact ${artifactName} not found on run ${process.env.RUN_ID}`); | |
| return; | |
| } | |
| const { data } = await github.rest.actions.downloadArtifact({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| artifact_id: artifact.id, | |
| archive_format: 'zip', | |
| }); | |
| fs.writeFileSync(`${dir}/qt.zip`, Buffer.from(data)); | |
| console.log(`Downloaded ${artifactName} (${artifact.size_in_bytes} bytes) from run ${process.env.RUN_ID}`); | |
| - name: Install Qt artifact | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| cd /tmp/qt-artifact | |
| unzip -o qt.zip | |
| expected=$(awk '{print $1}' "qt-${QT_VERSION}-ubuntu20.04.tar.xz.sha256") | |
| actual=$(sha256sum "qt-${QT_VERSION}-ubuntu20.04.tar.xz" | awk '{print $1}') | |
| echo "expected: ${expected}" | |
| echo "actual: ${actual}" | |
| test "${expected}" = "${actual}" || { echo "Qt artifact checksum mismatch" >&2; exit 1; } | |
| mkdir -p /opt/qt | |
| tar -C /opt/qt -xJf "qt-${QT_VERSION}-ubuntu20.04.tar.xz" 2>&1 | tee "${GITHUB_WORKSPACE}/logs/05-qt-install.log" | |
| "${QT_PREFIX}/bin/qmake" --version 2>&1 | tee -a "${GITHUB_WORKSPACE}/logs/05-qt-install.log" | |
| - name: Configure (Release, against TagLib ${TAGLIB_VERSION}) | |
| shell: bash | |
| env: | |
| CMAKE_PREFIX_PATH: /opt/qt/6.10.3:/usr/local:${{ env.TAGLIB_PREFIX }} | |
| PKG_CONFIG_PATH: ${{ matrix.taglib_pkgconfig }} | |
| LD_LIBRARY_PATH: /opt/qt/6.10.3/lib:/usr/local/lib:${{ env.TAGLIB_PREFIX }}/lib | |
| CC: gcc-12 | |
| CXX: g++-12 | |
| run: | | |
| set -o pipefail | |
| export PATH=/opt/qt/6.10.3/bin:$PATH | |
| cmake \ | |
| -S . -B build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DQT6=ON \ | |
| -DQML=ON \ | |
| -DBULK=ON \ | |
| -DFFMPEG=ON \ | |
| -DLOCALECOMPARE=ON \ | |
| -DMAD=ON \ | |
| -DMODPLUG=ON \ | |
| -DWAVPACK=ON \ | |
| -DBUILD_BENCH=OFF \ | |
| -DQTKEYCHAIN=OFF \ | |
| -DINSTALL_USER_UDEV_RULES=OFF \ | |
| 2>&1 | tee logs/07-cmake-configure.log | |
| echo '=== TagLib resolved by Mixxx ===' | |
| grep -iE 'TagLib' build/CMakeCache.txt || true | |
| grep -E 'Found TagLib|suitable version' logs/07-cmake-configure.log || true | |
| - name: Build (Release) | |
| shell: bash | |
| env: | |
| CMAKE_PREFIX_PATH: /opt/qt/6.10.3:/usr/local:${{ env.TAGLIB_PREFIX }} | |
| PKG_CONFIG_PATH: ${{ matrix.taglib_pkgconfig }} | |
| LD_LIBRARY_PATH: /opt/qt/6.10.3/lib:/usr/local/lib:${{ env.TAGLIB_PREFIX }}/lib | |
| CC: gcc-12 | |
| CXX: g++-12 | |
| run: | | |
| set -o pipefail | |
| export PATH=/opt/qt/6.10.3/bin:$PATH | |
| cmake --build build -j"$(nproc)" 2>&1 | tee logs/08-cmake-build.log | |
| - name: Verify linked TagLib version | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| lib=$(ldd build/mixxx 2>/dev/null | awk '/libtag\.so/{print $3}' | head -1) | |
| lib_real=$(realpath -e "${lib}" 2>/dev/null || echo "${lib}") | |
| echo "libtag resolved to: ${lib} (canonical: ${lib_real})" | |
| ldd build/mixxx 2>&1 | grep -i 'libtag' | tee logs/09-taglib-linkage.log | |
| case "${lib_real}" in | |
| ${TAGLIB_PREFIX}/*) | |
| echo "OK: mixxx links TagLib ${TAGLIB_VERSION} from ${TAGLIB_PREFIX}" | |
| ;; | |
| *) | |
| echo "FAIL: libtag is not from ${TAGLIB_PREFIX} (resolved: ${lib_real})" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| - name: Install Mixxx runtime tree | |
| shell: bash | |
| env: | |
| CMAKE_PREFIX_PATH: /opt/qt/6.10.3:/usr/local:${{ env.TAGLIB_PREFIX }} | |
| PKG_CONFIG_PATH: ${{ matrix.taglib_pkgconfig }} | |
| LD_LIBRARY_PATH: /opt/qt/6.10.3/lib:/usr/local/lib:${{ env.TAGLIB_PREFIX }}/lib | |
| CC: gcc-12 | |
| CXX: g++-12 | |
| run: | | |
| set -o pipefail | |
| export PATH=/opt/qt/6.10.3/bin:$PATH | |
| rm -rf "/opt/mixxx-${{ matrix.artifact_tag }}" | |
| cmake --install build --prefix "/opt/mixxx-${{ matrix.artifact_tag }}" \ | |
| 2>&1 | tee logs/10-cmake-install.log | |
| echo '=== Installed runtime tree ===' | |
| find "/opt/mixxx-${{ matrix.artifact_tag }}" -type f -printf '%P\n' \ | |
| | sort | tee logs/10-install-tree.log | |
| - name: Package Mixxx runtime (TagLib ${TAGLIB_VERSION}) | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| tar czf "/tmp/mixxx-${{ matrix.artifact_tag }}-runtime.tar.gz" -C "/opt/mixxx-${{ matrix.artifact_tag }}" . | |
| ls -lh "/tmp/mixxx-${{ matrix.artifact_tag }}-runtime.tar.gz" | |
| - name: Upload Mixxx runtime artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mixxx-${{ matrix.artifact_tag }}-runtime-${{ github.run_number }} | |
| path: /tmp/mixxx-${{ matrix.artifact_tag }}-runtime.tar.gz | |
| if-no-files-found: error | |
| - name: Collect diagnostics | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -o pipefail | |
| { | |
| echo '=== Git status ===' | |
| git status --short 2>/dev/null || true | |
| echo | |
| echo '=== CMake cache ===' | |
| grep -E '^(CMAKE_(BUILD_TYPE|CXX_COMPILER|C_COMPILER):|QT6:|FFMPEG:|TagLib|PC_TagLib)' build/CMakeCache.txt 2>/dev/null || true | |
| echo | |
| echo '=== Version strings ===' | |
| grep -E 'MIXXX_VERSION|VERSION_PRERELEASE' CMakeLists.txt | head -5 | |
| echo | |
| echo '=== TagLib install ===' | |
| ls -la "${TAGLIB_PREFIX}/lib/" 2>/dev/null | grep -i 'libtag' || true | |
| ls "${TAGLIB_PREFIX}/include/taglib/" 2>/dev/null | grep -i matroska || true | |
| } | tee logs/99-diagnostics.log | |
| - name: Upload logs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ubuntu-20.04-qt6-taglib22-build-${{ matrix.artifact_tag }}-${{ github.run_number }} | |
| path: logs/ | |
| if-no-files-found: warn | |
| retention-days: 14 |