-
Notifications
You must be signed in to change notification settings - Fork 112
[Windows] zlib 1.3.2 introduced a breaking change that broke the build of lua-zlib through LuaRocks #80
Description
Description
Important
The discussion below only applies to Windows.
Warning
This is a long issue description.
Recently, zlib 1.3.2 was released.
On the one hand, among enhancements and bug fixes, zlib 1.3.2 had a completely rewrite on their CMake support.
Note
CMake is one of the main build systems used by Windows developers to build C/C++ software from source nowadays.
On the other hand, due these changes targeting CMake support, zlib's developers introduced a breaking change:
- the DLL name changed (used to be
zlib1.dllon MSVC orlibzlib1.dllon MinGW/MinGW-w64, now it isz.dllon MSVC orlibz.dllon MinGW/MinGW-w64); - the name of the import library also changed (used to
zlib.libon MSVC orlibzlib.dll.aon MinGW/MinGW-w64, now it isz.libon MSVC orlibz.dll.aon MinGW/MinGW-w64);
Due these breaking changes explained above, whenever the user built zlib 1.3.2 from source with CMake, the build of lua-zlib through LuaRocks is going to fail.
Reproduction
I wrote a GitHub workflow to reproduce this issue comparing versions 1.3.1 and 1.3.2: log in to GitHub and inspect the runs https://github.com/luau-project/ci-tests/actions/runs/22404458107
Click here to toggle the workflow
name: lua-zlib test
on: push
jobs:
zlib-comparison:
runs-on: windows-latest
defaults:
run:
shell: cmd
strategy:
fail-fast: false
matrix:
lua-version:
- 5.5
- luajit
zlib-version:
- 1.3.1
- 1.3.2
toolchain:
- msvc
- gcc
env:
# usual directory that LuaRocks
# expects external dependencies
# to be
LUAROCKS_DEPS_DIR: C:\external
steps:
- name: Checkout
uses: actions/checkout@v6
with:
repository: brimworks/lua-zlib
ref: v1.4
- name: Restore zlib tarball from cache
id: restore-zlib
uses: actions/cache/restore@v5
with:
path: zlib-${{ matrix.zlib-version }}.tar.gz
key: zlib-${{ matrix.zlib-version }}
- name: Download zlib
if: ${{ steps.restore-zlib.outputs.cache-hit != 'true' }}
run: curl -L -O "https://zlib.net/fossils/zlib-${{ matrix.zlib-version }}.tar.gz"
- name: Save zlib tarball on cache
if: ${{ steps.restore-zlib.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v5
with:
path: zlib-${{ matrix.zlib-version }}.tar.gz
key: zlib-${{ matrix.zlib-version }}
- name: Extract zlib
run: tar -xf "zlib-${{ matrix.zlib-version }}.tar.gz"
- name: Setup MSVC developer prompt
uses: ilammy/msvc-dev-cmd@v1
if: ${{ matrix.toolchain == 'msvc' }}
- name: Configure zlib through CMake
run: |
IF "${{ matrix.toolchain }}" EQU "msvc" (
SET "CMAKE_GENERATOR=NMake Makefiles"
) ELSE (
SET "CMAKE_GENERATOR=MinGW Makefiles"
)
IF "${{ matrix.zlib-version }}" EQU "1.3.2" (
cmake -G "%CMAKE_GENERATOR%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DZLIB_BUILD_SHARED=ON ^
--install-prefix "${{ env.LUAROCKS_DEPS_DIR }}" ^
-S "zlib-${{ matrix.zlib-version }}" ^
-B "build-zlib"
) ELSE (
cmake -G "%CMAKE_GENERATOR%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_SHARED_LIBS=ON ^
--install-prefix "${{ env.LUAROCKS_DEPS_DIR }}" ^
-S "zlib-${{ matrix.zlib-version }}" ^
-B "build-zlib"
)
- name: Build zlib
run: cmake --build "build-zlib" --config Release
- name: Install zlib
run: cmake --install "build-zlib" --config Release
- name: Add the bin dir of LuaRocks external dependencies on PATH
run: echo ${{ env.LUAROCKS_DEPS_DIR }}\bin>>${{ github.path }}
- name: Show zlib installation directory
run: tree /F "${{ env.LUAROCKS_DEPS_DIR }}"
- name: Setup Lua and LuaRocks
uses: luau-project/setup-lua@v1
with:
lua-version: ${{ matrix.lua-version }}
- name: Show Lua version
run: lua -v
- name: Show LuaRocks version
run: luarocks --version
- name: Build and install lua-zlib
run: luarocks make "lua-zlib-scm-0.rockspec"Temporary and quick solutions to fix this build issue
- The easiest solution, which is far from the best scenario, is to ask users to stick to zlib version 1.3.1 or older
- The second solution, which is relatively easy to apply, is:
- For MSVC users willing to use zlib 1.3.2, ask them to copy the new import library (
z.lib) to the legacy import library (zlib.lib); - For MinGW/MinGW-w64 users with zlib 1.3.2, ask them to copy the new dll (
libz.dll) to the legacy dll (libzlib1.dll);
- For MSVC users willing to use zlib 1.3.2, ask them to copy the new import library (
The proper solution
The solution to handle both the legacy (1.3.1 and older) and current zlib versions through LuaRocks involve a comparison of versions to decide dynamically the correct import library to use.
There are ways to do that:
- with Makefiles (one for
nmake- the MSVC make, and another formingw32-make- the MinGW/MinGW-w64 make). This tends to be quite portable, becausenmakeis always installed with MSVC, and the user often hasmingw32-makein a MinGW/MinGW-w64 installation; - with CMake itself (would require CMake to be installed). Only C/C++ developers usually have this tool installed, so it is not too portable;
- with a custom build command (this is a sophisticated approach). Other libraries did it in the past (
luaposix, see https://luarocks.org/manifests/gvvaughan/luaposix-36.3-1.rockspec) through the tool https://github.com/gvvaughan/luke.
PS
In my view, ranking in portability order, the preferred methods to solve this issue would be: 1 - build command; 2 - Makefiles; 3 - CMake.
However, in a realistic scenario, Makefiles would provide the best balance between difficulty and time to market to solve this.
Note
Slowly, I'll investigate the build command and Makefiles solutions to this issue. However, I cannot guarantee anything.