Support building with musl libc (Alpine Linux) #216

Merged
peri4 merged 1 commits from alpine-musl-build into master 2026-08-30 20:11:58 +03:00
Owner

Что

Проект теперь собирается на Alpine Linux (musl libc) с дефолтными опциями CMake. Плюс зафиксирован латентный баг в PIThread, который проявился при этом.

Изменения (5 файлов, +36/−9)

Совместимость с musl:

  • pifile.cpp / pidir.cpp — LFS64-API (fopen64, fseeko64, ftello64, stat64, lstat64) теперь используется только там, где он реально существует (glibc/Windows/macOS — там, где собиралось до сих пор); для остальных libc (musl) — стандартный 64-битный POSIX API. Поведение на прежних платформах не меняется.
  • pithread.cpp — sched_param.__sched_priority (glibc-специфичный член) используется только под glibc, иначе sched_priority.
  • pimathbase.h — musl (C23) предоставляет глобальный pow10(double) в <math.h>, что конфликтовало с overload'ом PIP pow10(const double&) (амбигуость вызовов). Этот overload не объявляется там, где pow10 есть в системе; варианты float/ldouble не затронуты.

ICU:

  • Опция ICU теперь выключена по умолчанию: современный ICU (≥ 75) требует C++17 для своих заголовков, а проект компилируется в C++11. На Alpine (ICU 78) сборка падала именно на этом. При необходимости включается явно -DICU=ON (на системах со старым ICU).

Фикс бага (PIThread):

  • PIThread::setThreadName() вызывается изнутри только что запущенного потока и читала собственный хэндл PRIVATE->thread. Видимость хэндла в новом потоке до момента старта не гарантирована: в частности, musl pthread_create публикует его позже, чем glibc (проверено микробенчмарком: 199999/200000 NULL). На musl тест ClientServer.DynamicClients падал с SIGSEGV примерно в 20% прогонов (pthread_setname_np(0, …)). Фикс: переименовать вызывающий поток — pthread_setname_np(pthread_self(), …); канонический портативный паттерн, поведение на glibc идентичное.

Проверка (Alpine 3.24.1, musl 1.2.6, GCC 15.2, CMake 4.2.3)

  • полная сборка с дефолтными опциями (все модули + utils + тесты) — 0 ошибок;
  • все тесты: 7 сьютов, 338 тестов — 3 полных последовательных прогона без единого провала;
  • ClientServer.DynamicClients — 60/60 после фикса (до фикса падало ~6/30).

Требуемые пакеты Alpine: linux-headers zlib-dev libusb-dev libsodium-dev libmicrohttpd-dev curl-dev fftw-dev.

## Что Проект теперь собирается на Alpine Linux (musl libc) с дефолтными опциями CMake. Плюс зафиксирован латентный баг в `PIThread`, который проявился при этом. ## Изменения (5 файлов, +36/−9) **Совместимость с musl:** - `pifile.cpp` / `pidir.cpp` — LFS64-API (`fopen64`, `fseeko64`, `ftello64`, `stat64`, `lstat64`) теперь используется только там, где он реально существует (glibc/Windows/macOS — там, где собиралось до сих пор); для остальных libc (musl) — стандартный 64-битный POSIX API. Поведение на прежних платформах не меняется. - `pithread.cpp` — `sched_param.__sched_priority` (glibc-специфичный член) используется только под glibc, иначе `sched_priority`. - `pimathbase.h` — musl (C23) предоставляет глобальный `pow10(double)` в `<math.h>`, что конфликтовало с overload'ом PIP `pow10(const double&)` (амбигуость вызовов). Этот overload не объявляется там, где `pow10` есть в системе; варианты `float`/`ldouble` не затронуты. **ICU:** - Опция `ICU` теперь **выключена по умолчанию**: современный ICU (≥ 75) требует C++17 для своих заголовков, а проект компилируется в C++11. На Alpine (ICU 78) сборка падала именно на этом. При необходимости включается явно `-DICU=ON` (на системах со старым ICU). **Фикс бага (`PIThread`):** - `PIThread::setThreadName()` вызывается изнутри только что запущенного потока и читала собственный хэндл `PRIVATE->thread`. Видимость хэндла в новом потоке до момента старта не гарантирована: в частности, musl `pthread_create` публикует его позже, чем glibc (проверено микробенчмарком: 199999/200000 NULL). На musl тест `ClientServer.DynamicClients` падал с SIGSEGV примерно в 20% прогонов (`pthread_setname_np(0, …)`). Фикс: переименовать вызывающий поток — `pthread_setname_np(pthread_self(), …)`; канонический портативный паттерн, поведение на glibc идентичное. ## Проверка (Alpine 3.24.1, musl 1.2.6, GCC 15.2, CMake 4.2.3) - полная сборка с дефолтными опциями (все модули + utils + тесты) — 0 ошибок; - все тесты: 7 сьютов, 338 тестов — 3 полных последовательных прогона без единого провала; - `ClientServer.DynamicClients` — 60/60 после фикса (до фикса падало ~6/30). Требуемые пакеты Alpine: `linux-headers zlib-dev libusb-dev libsodium-dev libmicrohttpd-dev curl-dev fftw-dev`.
andrey force-pushed alpine-musl-build from 1b613e1b20 to 27498f03c5 2026-08-30 01:02:35 +03:00 Compare
andrey added 1 commit 2026-08-30 01:04:48 +03:00
- use LFS64 file/stat APIs only on glibc/Windows (absent in musl)
- use plain sched_priority outside glibc
- do not declare pow10(double) where the system provides C23 pow10() (musl)
- ICU is off by default: modern ICU (>= 75) needs C++17 for its headers,
  the project is built with C++11; enable explicitly with -DICU=ON
- fix latent crash: PIThread::setThreadName() read the thread handle from
  inside the new thread; the handle is not guaranteed to be visible before
  start (musl publishes it later), rename the calling thread via
  pthread_self() instead
andrey force-pushed alpine-musl-build from 27498f03c5 to 446eea404f 2026-08-30 01:04:48 +03:00 Compare
peri4 merged commit b1af66bee7 into master 2026-08-30 20:11:58 +03:00
Sign in to join this conversation.