Files

63 lines
4.1 KiB
Markdown
Raw Permalink Normal View History

2026-10-11 22:32:13 +03:00
# zlibreference.h
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
`zlibreference.h`, `zlibreference.cpp`
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Обход одной конкретной проблемы на Linux: Forge и NeoForge не ставятся на системах, где вместо
zlib стоит zlib-ng.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
## В чём проблема
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Установщики Forge и NeoForge собирают часть jar прямо на машине пользователя и сверяют sha1
каждого собранного файла с эталоном из `install_profile.json`. Эталон посчитан на обычном zlib.
CachyOS, Fedora и некоторые другие дистрибутивы ставят вместо него zlib-ng в режиме совместимости.
Он сжимает корректно, но результат побайтово другой. Поэтому установка падает на любой версии игры
с сообщением `Processor failed, invalid outputs`.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Другая Java не помогает: сборки OpenJDK под Linux берут `libz.so.1` из системы.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
## Что сделано
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
В репозитории лежат исходники zlib 1.3.1 (каталог `zlib/`). На Linux CMake собирает из них цель
`launcher_zlib_reference` (`libz.so.1`). В дереве сборки она лежит в `<папка бинарника>/zlib/`, при
установке — в `<prefix>/lib/BiLauncher/`. Сам лаунчер с ней не линкуется. Библиотека
подкладывается через `LD_PRELOAD` только процессу установщика, системный zlib-ng не трогается.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Исходники лежат в репозитории, а не скачиваются при сборке, по двум причинам: сборка не зависит от
сети, и версия зафиксирована. От версии зависит побайтовый результат сжатия.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
## Функции
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
На Windows и macOS все три функции ничего не делают: `systemIsZlibNg()` возвращает `false`,
`bundledPath()` пустую строку, `applyTo()` — `true`.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
### systemIsZlibNg()
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Открывает `libz.so.1` через `dlopen`, то есть ту же библиотеку, которую загрузчик выдаст процессу
java, и смотрит, есть ли `zlib-ng` в строке `zlibVersion()`. Результат вычисляется один раз за
запуск.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
### bundledPath()
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Ищет эталонную библиотеку по порядку:
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
1. `<applicationDirPath>/zlib/libz.so.1` — запуск из дерева сборки;
2. `<applicationDirPath>/../lib/BiLauncher/libz.so.1` — установленный пакет, tar.gz и AppImage;
3. `LAUNCHER_ZLIB_INSTALL_DIR/libz.so.1` — путь, заданный при конфигурации CMake.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
Второй вариант рассчитан на `CMAKE_INSTALL_LIBDIR=lib`. Поэтому CI на Ubuntu передаёт его явно,
иначе библиотека легла бы в `lib/x86_64-linux-gnu`.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
### applyTo(env, &note)
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
- zlib-ng в системе нет — подменять нечего, возвращает `true`, `note` пуст.
- zlib-ng есть, эталон найден — дописывает его путь в начало `LD_PRELOAD` (чужое содержимое
переменной сохраняется), возвращает `true`, в `note` пишет, что подставлено.
- zlib-ng есть, эталона нет — возвращает `false`, в `note` пишет предупреждение.
2026-09-03 09:16:56 +03:00
2026-10-11 22:32:13 +03:00
[ModLoaderInstaller](ModLoaderInstaller.md) пишет `note` в журнал установщика. Если `applyTo()`
вернула `false`, а установщик упал с ошибкой контрольных сумм, к ошибке добавляется прямая
подсказка про zlib-ng.
2026-09-03 09:16:56 +03:00
---
При создании этого документа использовался ИИ.