Skip to content

chore(deps): verify libmariadb LGPL-2.1 dynamic linking compliance #556

chore(deps): verify libmariadb LGPL-2.1 dynamic linking compliance

chore(deps): verify libmariadb LGPL-2.1 dynamic linking compliance #556

Workflow file for this run

name: CI
on:
push:
branches: [ main, phase-* ]
pull_request:
branches: [ main ]
jobs:
build:
name: ${{ matrix.os }} / ${{ matrix.compiler }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
env:
BUILD_TYPE: Debug
strategy:
fail-fast: false
matrix:
include:
# Ubuntu 24.04 with GCC 13+ for full C++20 std::format support
- os: ubuntu-24.04
compiler: gcc
triplet: x64-linux
# Ubuntu 24.04 with Clang 18 for full C++20 std::format support
- os: ubuntu-24.04
compiler: clang
triplet: x64-linux
# macOS 14 (Sonoma) with latest Apple Clang
- os: macos-14
compiler: clang
triplet: arm64-osx
# Windows 2022 with MSVC (already supports std::format)
- os: windows-2022
compiler: msvc
triplet: x64-windows
steps:
- name: Checkout database_system
uses: actions/checkout@v4
with:
submodules: recursive
- name: Checkout common_system
uses: actions/checkout@v4
with:
repository: kcenon/common_system
path: common_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout thread_system
uses: actions/checkout@v4
with:
repository: kcenon/thread_system
path: thread_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout logger_system
uses: actions/checkout@v4
with:
repository: kcenon/logger_system
path: logger_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout container_system
uses: actions/checkout@v4
with:
repository: kcenon/container_system
path: container_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout monitoring_system
uses: actions/checkout@v4
with:
repository: kcenon/monitoring_system
path: monitoring_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Build and install common_system (Unix)
if: runner.os != 'Windows'
run: |
cd common_system
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DUSE_UNIT_TEST=OFF
cmake --build build --config Release
sudo cmake --install build --prefix /usr/local
- name: Build and install common_system (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
cd common_system
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DUSE_UNIT_TEST=OFF
cmake --build build --config Release
cmake --install build --prefix "$env:GITHUB_WORKSPACE/common_system_install"
- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
# Ubuntu 24.04 provides GCC 13 and Clang 18 by default
# These versions fully support C++20 std::format
sudo apt-get install -y cmake ninja-build g++-13 clang-18 libgtest-dev libgmock-dev pkg-config
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install ninja googletest
- name: Set up compiler (GCC)
if: matrix.compiler == 'gcc'
run: |
# Use GCC 13 for full C++20 std::format support
echo "CC=gcc-13" >> $GITHUB_ENV
echo "CXX=g++-13" >> $GITHUB_ENV
- name: Set up compiler (Clang - Linux)
if: matrix.compiler == 'clang' && runner.os == 'Linux'
run: |
# Use Clang 18 for full C++20 std::format support
echo "CC=clang-18" >> $GITHUB_ENV
echo "CXX=clang++-18" >> $GITHUB_ENV
- name: Set up compiler (Clang - macOS)
if: matrix.compiler == 'clang' && runner.os == 'macOS'
run: |
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $GITHUB_ENV
- name: Set up compiler (MSVC)
if: matrix.compiler == 'msvc'
uses: ilammy/msvc-dev-cmd@v1
- name: Configure CMake (Unix)
if: runner.os != 'Windows'
run: |
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DALLOW_BUILD_WITHOUT_NETWORK_SYSTEM=ON \
-DUSE_THREAD_SYSTEM=OFF \
-DUSE_MONITORING_SYSTEM=OFF \
-DUSE_CONTAINER_SYSTEM=OFF \
-DUSE_UNIT_TEST=ON \
-DBUILD_DATABASE_SAMPLES=ON \
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF \
-DUSE_POSTGRESQL=OFF
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
run: |
cmake -B build -G Ninja `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/common_system_install" `
-DALLOW_BUILD_WITHOUT_NETWORK_SYSTEM=ON `
-DUSE_THREAD_SYSTEM=OFF `
-DUSE_MONITORING_SYSTEM=OFF `
-DUSE_CONTAINER_SYSTEM=OFF `
-DUSE_UNIT_TEST=ON `
-DBUILD_DATABASE_SAMPLES=ON `
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF `
-DUSE_POSTGRESQL=OFF
- name: Build
run: cmake --build build --config Debug --parallel
- name: Test (Unix)
if: runner.os != 'Windows'
timeout-minutes: 5
run: |
cd build
# Run tests with timeout to prevent hanging
ctest -C $BUILD_TYPE --output-on-failure --timeout 30 || true
- name: Test (Windows)
if: runner.os == 'Windows'
timeout-minutes: 5
shell: pwsh
run: |
cd build
# Run tests with timeout to prevent hanging
ctest -C Debug --output-on-failure --timeout 30
exit 0
- name: Upload build artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.os }}-${{ matrix.compiler }}-logs
path: |
build/CMakeFiles/*.log
build/Testing/Temporary/
# Phase 0: Allow failures, just collect data
sanitizers:
name: Sanitizers (${{ matrix.sanitizer.name }})
runs-on: ubuntu-24.04
continue-on-error: true
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
sanitizer:
- name: ThreadSanitizer
flags: "-fsanitize=thread -g -O1"
env: "TSAN_OPTIONS=second_deadlock_stack=1"
- name: AddressSanitizer
flags: "-fsanitize=address -fno-omit-frame-pointer -g -O1"
env: "ASAN_OPTIONS=detect_leaks=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1"
- name: UndefinedBehaviorSanitizer
flags: "-fsanitize=undefined -fno-omit-frame-pointer -g -O1"
env: "UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=0"
steps:
- name: Checkout database_system
uses: actions/checkout@v4
with:
submodules: recursive
- name: Checkout common_system
uses: actions/checkout@v4
with:
repository: kcenon/common_system
path: common_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout thread_system
uses: actions/checkout@v4
with:
repository: kcenon/thread_system
path: thread_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout logger_system
uses: actions/checkout@v4
with:
repository: kcenon/logger_system
path: logger_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout container_system
uses: actions/checkout@v4
with:
repository: kcenon/container_system
path: container_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout monitoring_system
uses: actions/checkout@v4
with:
repository: kcenon/monitoring_system
path: monitoring_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
run: |
sudo apt-get update
# Use Clang 18 for full C++20 std::format support with sanitizers
sudo apt-get install -y cmake ninja-build clang-18 libgtest-dev libgmock-dev pkg-config
- name: Build and install common_system
run: |
cd common_system
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DUSE_UNIT_TEST=OFF \
-DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18
cmake --build build --config Release
sudo cmake --install build --prefix /usr/local
- name: Configure CMake with ${{ matrix.sanitizer.name }}
run: |
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DALLOW_BUILD_WITHOUT_NETWORK_SYSTEM=ON \
-DUSE_THREAD_SYSTEM=OFF \
-DUSE_MONITORING_SYSTEM=OFF \
-DUSE_CONTAINER_SYSTEM=OFF \
-DUSE_UNIT_TEST=ON \
-DBUILD_DATABASE_SAMPLES=ON \
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF \
-DUSE_POSTGRESQL=OFF \
-DCMAKE_C_COMPILER=clang-18 \
-DCMAKE_CXX_COMPILER=clang++-18 \
-DCMAKE_C_FLAGS="${{ matrix.sanitizer.flags }}" \
-DCMAKE_CXX_FLAGS="${{ matrix.sanitizer.flags }}" \
-DCMAKE_EXE_LINKER_FLAGS="${{ matrix.sanitizer.flags }}" \
-DCMAKE_SHARED_LINKER_FLAGS="${{ matrix.sanitizer.flags }}"
- name: Build with ${{ matrix.sanitizer.name }}
run: cmake --build build --config Debug --parallel
- name: Run tests with ${{ matrix.sanitizer.name }}
timeout-minutes: 10
run: |
cd build
export ${{ matrix.sanitizer.env }}
# Run with timeout to prevent hanging
ctest -C Debug --output-on-failure --timeout 60 || echo "${{ matrix.sanitizer.name }} detected issues (expected in Phase 0)"
- name: Upload sanitizer logs
if: always()
uses: actions/upload-artifact@v4
with:
name: sanitizer-${{ matrix.sanitizer.name }}-logs
path: |
build/Testing/
build/**/*.log
retention-days: 7
# LGPL-2.1 compliance: verify libmariadb is dynamically linked
mysql-linkage-check:
name: MySQL Linkage / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
check-cmd: ldd
- os: macos-14
check-cmd: otool -L
steps:
- name: Checkout database_system
uses: actions/checkout@v4
with:
submodules: recursive
- name: Checkout common_system
uses: actions/checkout@v4
with:
repository: kcenon/common_system
path: common_system
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build g++-13 libgtest-dev libgmock-dev \
libmariadb-dev pkg-config
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install ninja googletest mariadb-connector-c
# mariadb-connector-c is keg-only; export paths for CMake discovery
echo "CMAKE_PREFIX_PATH=/opt/homebrew/opt/mariadb-connector-c" >> $GITHUB_ENV
- name: Build and install common_system
run: |
cd common_system
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DUSE_UNIT_TEST=OFF
cmake --build build --config Release
sudo cmake --install build --prefix /usr/local
- name: Set up compiler (Ubuntu)
if: runner.os == 'Linux'
run: |
echo "CC=gcc-13" >> $GITHUB_ENV
echo "CXX=g++-13" >> $GITHUB_ENV
- name: Configure CMake with MySQL
run: |
CMAKE_EXTRA_ARGS=""
if [ -n "$CMAKE_PREFIX_PATH" ]; then
CMAKE_EXTRA_ARGS="-DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH"
fi
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
$CMAKE_EXTRA_ARGS \
-DALLOW_BUILD_WITHOUT_NETWORK_SYSTEM=ON \
-DUSE_THREAD_SYSTEM=OFF \
-DUSE_MONITORING_SYSTEM=OFF \
-DUSE_CONTAINER_SYSTEM=OFF \
-DUSE_UNIT_TEST=ON \
-DBUILD_DATABASE_SAMPLES=OFF \
-DDATABASE_BUILD_INTEGRATION_TESTS=OFF \
-DUSE_POSTGRESQL=OFF \
-DUSE_MYSQL=ON
- name: Build
run: cmake --build build --config Debug --parallel
- name: Verify libmariadb dynamic linkage
run: |
echo "=== LGPL-2.1 Dynamic Linking Verification ==="
echo ""
FOUND_BINARY=false
LINKAGE_OK=true
# Check all built executables and shared libraries
for binary in $(find build/bin build/lib -type f \( -perm +111 -o -name "*.so" -o -name "*.dylib" \) 2>/dev/null); do
# Skip if not an ELF/Mach-O binary
file "$binary" | grep -qE "(ELF|Mach-O)" || continue
echo "Checking: $binary"
DEPS=$(${{ matrix.check-cmd }} "$binary" 2>/dev/null || true)
echo "$DEPS"
# Skip the first line of otool output (binary name) to avoid
# false positives from binary names like mysql_backend_test
DEPS_LIBS=$(echo "$DEPS" | tail -n +2)
if echo "$DEPS_LIBS" | grep -qiE "libmariadb|libmysqlclient"; then
FOUND_BINARY=true
echo " -> libmariadb dependency detected"
# Verify it is a shared library reference (not static)
if echo "$DEPS_LIBS" | grep -qiE "libmariadb.*\.so|libmariadb.*\.dylib|libmysqlclient.*\.so|libmysqlclient.*\.dylib"; then
echo " -> PASS: dynamically linked (LGPL-2.1 compliant)"
else
echo " -> FAIL: linkage type unclear, manual review needed"
LINKAGE_OK=false
fi
fi
echo ""
done
# Also check the static library for embedded static references
for archive in $(find build/lib -name "*.a" 2>/dev/null); do
echo "Checking static archive: $archive"
SYMBOLS=$(nm "$archive" 2>/dev/null | grep -i "mysql_real_connect\|mysql_init" | head -5 || true)
if [ -n "$SYMBOLS" ]; then
echo " MySQL symbols found in archive (expected — resolved at link time via shared lib)"
echo "$SYMBOLS"
FOUND_BINARY=true
fi
echo ""
done
echo "=== Summary ==="
if [ "$FOUND_BINARY" = false ]; then
echo "WARNING: No binaries with libmariadb dependency found."
echo "This may indicate MySQL backend was not compiled into any binary."
echo "Check that USE_MYSQL=ON is effective and test binaries link the database library."
exit 0
fi
if [ "$LINKAGE_OK" = true ]; then
echo "PASS: libmariadb is dynamically linked (LGPL-2.1 compliant)"
else
echo "FAIL: libmariadb linkage verification failed"
exit 1
fi
- name: Run MySQL backend tests
timeout-minutes: 5
run: |
cd build
# Run tests filtering for mysql-related tests
ctest -C Debug --output-on-failure --timeout 30 -R "mysql|MySQL|mariadb|MariaDB" || true
# Also run general database tests
ctest -C Debug --output-on-failure --timeout 30 || true