Repository navigation
build: statically link OpenSSL so released binaries need no runtime deps - #35
Conversation
…ributable binaries The released shared libraries are supposed to be usable as-is, without the consumer installing anything. They were not: - macOS: libfakelua.dylib had absolute Homebrew paths baked in (/opt/homebrew/opt/openssl@3/lib/libssl.3.dylib), so it only loaded on machines with that exact prefix. Any other Mac got "dyld: Library not loaded". - Windows: libfakelua.dll needed libssl-3-x64.dll, libcrypto-3-x64.dll, libgcc_s_seh-1.dll, libwinpthread-1.dll and libstdc++-6.dll, none of which shipped in the release zip. Link OpenSSL statically via OPENSSL_USE_STATIC_LIBS, behind a new FAKELUA_PREFER_STATIC_DEPS option (default ON). On MinGW also statically link libgcc and winpthread. libstdc++/libc++ stay dynamic on purpose: include/fakelua.h exposes STL types across the ABI boundary (std::string returned by value, std::vector<std::pair<...>>) and ViToString() is implemented inline in that header, so host and library must share a single copy of libstdc++. Linking it statically would give each side its own copy and corrupt the heap when a std::string crosses the boundary. A configure-time warning fires if OpenSSL resolves to shared libs anyway (e.g. an OpenSSL install without the .a files), so the regression can't come back silently. Verified on macOS: otool -L now reports only /usr/lib/libc++.1.dylib and /usr/lib/libSystem.B.dylib; test_crypto.* and test_http.tls_echo (60 tests) all pass.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #35 +/- ##
==========================================
- Coverage 88.07% 88.07% -0.01%
==========================================
Files 124 124
Lines 25494 25498 +4
==========================================
+ Hits 22454 22457 +3
- Misses 3040 3041 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Static OpenSSL on MinGW broke 8 test_crypto cases (rc4 / blowfish / des). Those algorithms live in OpenSSL 3's "legacy" provider, a loadable module found via the MODULESDIR compiled into libcrypto; MSYS2 bakes in the MSYS path "/mingw64/lib/ossl-modules", which Win32 LoadLibrary cannot resolve. The shared libcrypto derives the module dir from its own DLL location, so it finds legacy.dll. Also warn (instead of silently ignoring) when the legacy provider fails to load, and extend the static-lib guard to catch MinGW/MSVC import libraries.
|
Windows CI 失败原因已定位并修复(8f0a989)。 根因:
我在 macOS 上用 修法:MinGW 上 OpenSSL 保持动态(macOS/Linux 仍静态,libgcc/winpthread 仍静态),并把 legacy 加载失败从静默改成打 WARN。MinGW 发布包仍需随附 代价说明:想让 Windows 也静态,就得在 configure 期把 ossl-modules 目录(经 cygpath 转 Windows 路径)烘进二进制再 |
背景
发布的动态库本该"下载即用",实际上不是:
libfakelua.dylib里硬编码了绝对路径/opt/homebrew/opt/openssl@3/lib/libssl.3.dylib,换台没装同款 Homebrew openssl 的机器直接dyld: Library not loaded。libfakelua.dll需要libssl-3-x64.dll、libcrypto-3-x64.dll、libgcc_s_seh-1.dll、libwinpthread-1.dll、libstdc++-6.dll,release 包里一个都没带。libssl.so.3/libcrypto.so.3,多数发行版自带,风险最低。(实测方式:下载 v2.0.0 三个 release 包,
otool -L/strings查依赖,非推测。)改动
新增
FAKELUA_PREFER_STATIC_DEPS选项(默认 ON):OPENSSL_USE_STATIC_LIBS=TRUE→ OpenSSL 静态链入-static-libgcc+-Wl,-Bstatic -lwinpthread -Wl,-Bdynamiclibstdc++ / libc++ 刻意保持动态。原因是
include/fakelua.h在 ABI 边界暴露了 STL 类型(std::string按值返回、std::vector<std::pair<...>>),且ViToString()是在头文件里 inline 实现的 —— 宿主会自己编译这段代码。如果静态链 libstdc++,宿主和库各有一份,std::string跨边界时就是两套 allocator,直接踩堆损坏。libgcc / winpthread 是纯 C 级运行时,没有这层 ABI 面,可以安全静态。另外加了个配置期守卫:万一 OpenSSL 仍解析到动态库(比如某个安装没带
.a),configure 时打 WARNING,避免这个坑悄悄回归。效果(macOS 实测)
体积 9.2M → 14M(静态 OpenSSL 约 +5MB)。
验证
otool -L已无 openssltest_crypto.*+test_http.tls_echo共 60 个测试全过(含真实 TLS 握手)libssl-dev的.a是否带-fPIC。若不是,链进.so时会报relocation ... can not be used when making a shared object,需要针对 Linux 关掉静态或改用别的方式。mingw-w64-x86_64-openssl提供的libssl.a通常是 DLL 的导入库而非静态归档。若如此,Windows 端libssl-3-x64.dll/libcrypto-3-x64.dll仍会需要 —— 那就得在打包时把这两个 DLL 一起放进 zip(见后续工作)。后续(不在此 PR)
release.yml目前是手工cp打包,没跑cmake --install,所以下载的包里没有lib/cmake/fakelua/,README 教的find_package(fakelua)对下载包不成立。include/fakelua.h的FAKELUA_VERSION_STRING,否则 release workflow 不触发。