- .gitea/workflows/release.yml: по тегу vX.Y.Z черновик релиза, три сборки
(Inno Setup + portable zip, AppImage + tar.gz, universal DMG), SHA256SUMS
и публикация; workflow_dispatch собирает артефакты без релиза.
- ci/setup-runner-{linux.sh,windows.ps1}: подготовка раннеров поверх уже
установленного Qt (компилятор, git, node, appimagetool/Inno, gitea-runner).
- packaging/: THIRD_PARTY_LICENSES.txt (без него падал cmake --install на
Windows/Linux) и скрипт установщика Inno Setup.
- Linux: недостающий #include <QCoreApplication> в zlibreference.cpp и
OUTPUT_DIRECTORY QML-модуля — каталог BiLauncher в build-dir совпадал с
именем исполняемого файла, и линковка падала.
- Из ресурсов убраны неиспользуемые mp4 и дубли icon.rc; из git — icon.rc
(генерируется из icon.rc.in) и doc/.DS_Store.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
#include "zlibreference.h"
|
|
#include "localization.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
#include <QProcessEnvironment>
|
|
#include <QStringList>
|
|
|
|
#include <utility>
|
|
|
|
#if defined(Q_OS_LINUX)
|
|
#include <dlfcn.h>
|
|
#endif
|
|
|
|
bool ZlibReference::systemIsZlibNg()
|
|
{
|
|
#if defined(Q_OS_LINUX)
|
|
// Спрашиваем ровно ту библиотеку, которую подберёт ld.so процессу java.
|
|
// zlib-ng в режиме совместимости честно пишет о себе в zlibVersion().
|
|
static const bool result = [] {
|
|
void *handle = dlopen("libz.so.1", RTLD_LAZY);
|
|
if (!handle)
|
|
return false;
|
|
using VersionFn = const char *(*)();
|
|
const auto zlibVersion = reinterpret_cast<VersionFn>(dlsym(handle, "zlibVersion"));
|
|
const QString version = zlibVersion ? QString::fromLatin1(zlibVersion()) : QString();
|
|
dlclose(handle);
|
|
return version.contains(QLatin1String("zlib-ng"), Qt::CaseInsensitive);
|
|
}();
|
|
return result;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
QString ZlibReference::bundledPath()
|
|
{
|
|
#if defined(Q_OS_LINUX)
|
|
static const QString path = [] {
|
|
QStringList candidates;
|
|
const QString appDir = QCoreApplication::applicationDirPath();
|
|
if (!appDir.isEmpty()) {
|
|
candidates << appDir + QStringLiteral("/zlib/libz.so.1") // дерево сборки
|
|
<< appDir + QStringLiteral("/../lib/BiLauncher/libz.so.1");
|
|
}
|
|
#ifdef LAUNCHER_ZLIB_INSTALL_DIR
|
|
candidates << QStringLiteral(LAUNCHER_ZLIB_INSTALL_DIR) + QStringLiteral("/libz.so.1");
|
|
#endif
|
|
for (const QString &candidate : std::as_const(candidates)) {
|
|
const QFileInfo info(candidate);
|
|
if (info.exists() && info.isFile())
|
|
return info.canonicalFilePath();
|
|
}
|
|
return QString();
|
|
}();
|
|
return path;
|
|
#else
|
|
return {};
|
|
#endif
|
|
}
|
|
|
|
bool ZlibReference::applyTo(QProcessEnvironment &env, QString *note)
|
|
{
|
|
#if defined(Q_OS_LINUX)
|
|
if (!systemIsZlibNg()) {
|
|
if (note)
|
|
note->clear();
|
|
return true;
|
|
}
|
|
|
|
const QString path = bundledPath();
|
|
if (path.isEmpty()) {
|
|
if (note)
|
|
*note = Loc::text("zlib.warning.referenceMissing");
|
|
return false;
|
|
}
|
|
|
|
// Не затираем чужой LD_PRELOAD: наш идёт первым, остальное остаётся.
|
|
const QString existing = env.value(QStringLiteral("LD_PRELOAD"));
|
|
env.insert(QStringLiteral("LD_PRELOAD"), existing.isEmpty() ? path : path + u':' + existing);
|
|
if (note)
|
|
*note = Loc::text("zlib.status.preloaded")
|
|
.arg(QDir::toNativeSeparators(path));
|
|
return true;
|
|
#else
|
|
Q_UNUSED(env);
|
|
if (note)
|
|
note->clear();
|
|
return true;
|
|
#endif
|
|
}
|