Skip to content

Fix symbol mangling and prefix gz_error#2097

Merged
Dead2 merged 1 commit intozlib-ng:developfrom
mtl1979:mangle-map
Jan 14, 2026
Merged

Fix symbol mangling and prefix gz_error#2097
Dead2 merged 1 commit intozlib-ng:developfrom
mtl1979:mangle-map

Conversation

@mtl1979
Copy link
Copy Markdown
Collaborator

@mtl1979 mtl1979 commented Jan 12, 2026

  • We need to mangle symbols in the map file, otherwise none of the symbols are exported

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 12, 2026

Walkthrough

Generate version-script maps from templates into the build directory, reference generated maps in linker flags, ignore generated maps in Git, add map cleanup to distclean, and route internal gz_error calls through the PREFIX macro via header and call-site updates.

Changes

Cohort / File(s) Summary
Build configuration
CMakeLists.txt, Makefile.in, configure
Add configure-time generation of zlib${SUFFIX}.map from .map.in; update linker -Wl,--version-script to point at the build-dir map; include generated map in distclean.
Version map templates
zlib.map.in, zlib-ng.map.in
New .map.in files declaring hierarchical, versioned symbol maps with @ZLIB_SYMBOL_PREFIX@ placeholders and global/local sections.
Git housekeeping
.gitignore
Add zlib.map and zlib-ng.map to ignore list.
Internal symbol prefixing
gzguts.h, gzlib.c, gzread.c, gzwrite.c
Rename internal gz_error declaration and all call sites to PREFIX(gz_error)(...) via macro to change symbol name while preserving behavior.

Possibly related PRs

Suggested labels

Build Env, Compatibility

Suggested reviewers

  • Dead2
  • nmoinvaz
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description is directly related to the changeset, explaining that symbols need to be mangled in the map file for proper export from the shared library.
Title check ✅ Passed The title accurately summarizes the main changes: fixing symbol mangling and prefixing gz_error, which directly address the core PR objective of ensuring symbols are correctly mangled in the map file for proper export.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83a14aa and 3252c10.

⛔ Files ignored due to path filters (2)
  • zlib-ng.map is excluded by !**/*.map
  • zlib.map is excluded by !**/*.map
📒 Files selected for processing (6)
  • .gitignore
  • CMakeLists.txt
  • Makefile.in
  • configure
  • zlib-ng.map.in
  • zlib.map.in
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1925
File: arch/loongarch/lasxintrin_ext.h:38-65
Timestamp: 2025-07-04T16:59:44.725Z
Learning: In zlib-ng, the policy for supporting old compilers is to maintain compatibility for up to two years after GitHub removes support for them in CI, or when there is no long-time contributor left testing for the architecture if the architecture was not supported by GitHub Actions at all.
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2001
File: test/CMakeLists.txt:10-12
Timestamp: 2025-11-15T12:43:50.353Z
Learning: In zlib-ng, the TEST_STOCK_ZLIB CMake variable is intentionally not defined as a CMake option. It's meant to be set manually via command-line (e.g., -DTEST_STOCK_ZLIB=ON) when testing against stock zlib. The testing workflow for stock zlib requires undocumented manual steps and is considered experimental/incomplete.
📚 Learning: 2025-11-15T12:43:50.353Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2001
File: test/CMakeLists.txt:10-12
Timestamp: 2025-11-15T12:43:50.353Z
Learning: In zlib-ng, the TEST_STOCK_ZLIB CMake variable is intentionally not defined as a CMake option. It's meant to be set manually via command-line (e.g., -DTEST_STOCK_ZLIB=ON) when testing against stock zlib. The testing workflow for stock zlib requires undocumented manual steps and is considered experimental/incomplete.

Applied to files:

  • .gitignore
  • CMakeLists.txt
  • zlib-ng.map.in
📚 Learning: 2025-12-05T19:54:22.258Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2039
File: CMakeLists.txt:121-121
Timestamp: 2025-12-05T19:54:22.258Z
Learning: In zlib-ng CMakeLists.txt, for cmake_dependent_option calls with single variable dependencies (e.g., ARCH_32BIT, ARCH_64BIT), quotes around the dependency variable are optional and not required by CMake. Quotes are only necessary for complex conditions with operators or spaces.

Applied to files:

  • .gitignore
  • CMakeLists.txt
📚 Learning: 2025-07-04T16:59:44.725Z
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1925
File: arch/loongarch/lasxintrin_ext.h:38-65
Timestamp: 2025-07-04T16:59:44.725Z
Learning: In zlib-ng, the policy for supporting old compilers is to maintain compatibility for up to two years after GitHub removes support for them in CI, or when there is no long-time contributor left testing for the architecture if the architecture was not supported by GitHub Actions at all.

Applied to files:

  • .gitignore
  • CMakeLists.txt
  • zlib-ng.map.in
  • zlib.map.in
📚 Learning: 2025-10-12T17:01:13.630Z
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1980
File: compress.c:31-33
Timestamp: 2025-10-12T17:01:13.630Z
Learning: In zlib-ng, when ZLIB_COMPAT is defined, z_int32_t is typedef'd as `int` (not int32_t), and zlib.h is included (which uses `int` in function signatures). This allows the implementation to use z_int32_t while maintaining backwards compatibility with the original zlib API that uses `int`. When ZLIB_COMPAT is not defined, z_int32_t is typedef'd as int32_t and zlib-ng.h is used instead.

Applied to files:

  • CMakeLists.txt
  • zlib-ng.map.in
  • zlib.map.in
📚 Learning: 2025-08-20T14:34:15.867Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 1928
File: gzwrite.c:0-0
Timestamp: 2025-08-20T14:34:15.867Z
Learning: Z_VERSION_ERROR is used by zlib but not by zlib-ng, so it should not be included in error handling for zlib-ng deflateInit2() calls.

Applied to files:

  • zlib-ng.map.in
  • zlib.map.in
📚 Learning: 2025-07-04T20:17:58.531Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 1928
File: gzlib.c:90-90
Timestamp: 2025-07-04T20:17:58.531Z
Learning: In zlib-ng's gz_buffer_alloc() function, the condition `(out_mult >= 1 && state->out == NULL)` is necessary because state->out is intentionally left as NULL when out_mult == 0 (write + direct mode), but should be allocated when out_mult >= 1. The condition properly distinguishes between intentionally NULL buffers and allocation failures.

Applied to files:

  • zlib-ng.map.in
📚 Learning: 2025-05-13T06:56:12.407Z
Learnt from: samrussell
Repo: zlib-ng/zlib-ng PR: 1914
File: arch/generic/crc32_chorba_c.c:30-32
Timestamp: 2025-05-13T06:56:12.407Z
Learning: In zlib-ng, pointer casts between z_word_t* and uint64_t* are safe because: 1) On 64-bit platforms, z_word_t is defined as uint64_t, making the cast a no-op; 2) On 32-bit platforms where z_word_t is uint32_t, the code paths using uint64_t* are skipped in favor of 32-bit specific implementations.

Applied to files:

  • zlib-ng.map.in
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (102)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows ClangCl Win64 Native Instructions (AVX)
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu MinGW i686
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
  • GitHub Check: macOS GCC UBSAN (ARM64)
  • GitHub Check: Windows MSVC 2022 v141 Win32
  • GitHub Check: macOS Clang Native Instructions (Intel)
  • GitHub Check: EL10 Clang S390X DFLTCC MSAN
  • GitHub Check: Windows MSVC 2022 v141 Win64
  • GitHub Check: Windows ClangCl Win64 Native Instructions (AVX)
  • GitHub Check: Windows MSVC 2022 v143 Win64
  • GitHub Check: Windows MSVC ARM64 No Test
  • GitHub Check: Windows GCC
  • GitHub Check: Ubuntu MinGW i686
  • GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
  • GitHub Check: Ubuntu GCC No CTZLL
  • GitHub Check: macOS GCC Symbol Prefix (ARM64)
🔇 Additional comments (7)
.gitignore (1)

28-34: LGTM!

The ignore entries correctly match the generated map files (zlib.map for compat mode and zlib-ng.map for zlib-ng mode) that are produced by the configure script from the corresponding .map.in templates.

Makefile.in (1)

384-384: LGTM!

The distclean target correctly removes the generated zlib${SUFFIX}.map file, consistent with how other generated files using the ${SUFFIX} pattern are handled.

configure (1)

744-745: LGTM!

The map file generation correctly:

  1. Uses sed to substitute @ZLIB_SYMBOL_PREFIX@ with the configured symbol_prefix
  2. Generates the map in the build directory (zlib${SUFFIX}.map)
  3. References the generated map via BUILDDIR/$MAPNAME in the linker flags

This ensures symbols are properly mangled in the version script, fixing the export issue described in the PR.

zlib-ng.map.in (2)

1-9: Version blocks are not chained.

Unlike zlib.map.in where version blocks chain to parent versions (e.g., } ZLIB_1.2.0;), the blocks here are standalone. This is likely intentional for zlib-ng since it doesn't need to maintain symbol versioning compatibility with older zlib versions, but please confirm this is the intended behavior.


109-111: FAIL block correctly hides unlisted symbols.

The FAIL { local: *; }; block ensures any symbol not explicitly listed in the global sections is hidden. This is a good catch-all safety mechanism for symbol visibility.

zlib.map.in (1)

1-98: LGTM - Symbol versioning map for zlib compatibility mode.

The version script correctly:

  1. Uses proper version chaining from ZLIB_1.2.0 through ZLIB_1.2.12
  2. Lists symbols introduced in each version
  3. Marks internal symbols as local in the base ZLIB_1.2.0 block
  4. Uses the @ZLIB_SYMBOL_PREFIX@ placeholder consistently for symbol mangling

The symbol additions per version align with the historical zlib API evolution.

CMakeLists.txt (1)

1561-1564: LGTM! Correct approach for generating version-script with symbol mangling.

Using configure_file() to process the .map.in template allows @VARIABLE@ placeholders (e.g., symbol prefix) to be substituted at configure time. Placing the generated map in CMAKE_CURRENT_BINARY_DIR follows CMake best practices for build artifacts.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 22.22222% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.56%. Comparing base (83a14aa) to head (82979cb).
⚠️ Report is 8 commits behind head on develop.

Files with missing lines Patch % Lines
gzread.c 16.66% 9 Missing and 1 partial ⚠️
gzwrite.c 10.00% 9 Missing ⚠️
gzlib.c 60.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2097      +/-   ##
===========================================
- Coverage    83.93%   83.56%   -0.38%     
===========================================
  Files          156      156              
  Lines        13184    13184              
  Branches      3211     3214       +3     
===========================================
- Hits         11066    11017      -49     
- Misses        1061     1130      +69     
+ Partials      1057     1037      -20     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mtl1979 mtl1979 marked this pull request as ready for review January 12, 2026 03:20
@mtl1979
Copy link
Copy Markdown
Collaborator Author

mtl1979 commented Jan 12, 2026

CodeCov failures are partially because runner didn't have AVX512 support and partially because we don't test most error conditions in gzip support code.

@Dead2
Copy link
Copy Markdown
Member

Dead2 commented Jan 12, 2026

If we want to prefix gz_error, the new one ahould go into a new group 'ZLIB_NG_2.3.3'.
To maintain strict ABI compatibility, the old un-prefixed gz_error should still remain in ZLIB_NB_2.0.0 though.
But it is a local function and I don't think it could ever be referenced from outside, so I'm not sure why it is in the map at all..

We don't have many Z_INTERNAL symbols in the map at all. Take for example zng_tr_init(), it is not in the map and it is not prefixed.
The other local symbols in that list are things I can imagine at least being made available from the outside (alloc functions through pointers in strm for example, not that that is more useful with the map entry).

According to what I can find online, linkers use the local list to exclude those symbols from being exported, and usually don't include information about them in the binary, unless extra symbol debugging info is specifically enabled. But normal debuginfo also includes this and more, possibly this would be useful for closed-source debugging where you don't want to export the full debuginfo.
So, since we already set the symbols as Z_INTERNAL in the code, the local entries are not useful for anything as far as I can tell. They are annoying and a maintenance burden though, since they introduce prefixing to internal functions.


My suggestion: Remove gz_error from at least the zlib-ng.map file, possibly from zlib.map as well. Nothing should have linked against it, so it should also not be possible to break anything.
This also lets us avoid both prefixing and symbol_prefixing.

AFAICT: None of the internal symbols should need symbol prefixing, and likely not prefixing either.
The only case where I can conceive that either prefix method would be needed for local symbols would be if the map files are specifically used to check for conflicts, and that would be fixed by not having them listed there in the first place.

Am I wrong?

Since I was worried I was missing something, I did confer with Google's AI and ChatGPT in case they had some further insight, but they both concluded pretty much the same, with Google being the more concise:

Thinking. Searching.
Including internal symbols such as gz_error in the local: section of a linker map file for zlib-ng is redundant and adds to maintenance costs.
AI responses may include mistakes. Learn more

That has to be the shortest most concise AI reply I have ever gotten to something like this. 👀

So, perhaps drop the gz_error prefixing changes and instead add a commit removing gz_error from the .map and mangling files?

@mtl1979
Copy link
Copy Markdown
Collaborator Author

mtl1979 commented Jan 12, 2026

@Dead2 We still need the mangling for static builds. I didn't check when the catch all local was added but the default is global for any unlisted symbols as is still case for zlib-compat

Because static builds don't have symbol versioning, we can't introduce zng_gz_error as a new local symbol, as it would require adding the unprefixed symbol as alias, and that would "again" break compiling against both stock zlib and zlib-ng. It's a compromise, but actually found by AI bot as seen in the resolved reviews.

@Dead2
Copy link
Copy Markdown
Member

Dead2 commented Jan 12, 2026

@Dead2 We still need the mangling for static builds. I didn't check when the catch all local was added but the default is global for any unlisted symbols as is still case for zlib-compat

Since we use Z_INTERNAL for all internal functions, that already makes the symbols unreachable and invisible from the outside. This is something zlib does not do though, but we have done so since before our first release and we have had no complaints about that.

This is also why the catch all local is named FAIL, so that we can in effect grep for it (I guess we should have added a CI test for that actually).

$ nm -D build/libz-ng.so|grep FAIL
0000000000000000 A FAIL

It contains no symbols because they are all marked as internal in the source code.
The internal symbols can not conflict with anything either. The mapped ones can potentially.

Because static builds don't have symbol versioning, we can't introduce zng_gz_error as a new local symbol, as it would require adding the unprefixed symbol as alias, and that would "again" break compiling against both stock zlib and zlib-ng. It's a compromise, but actually found by AI bot as seen in the resolved reviews.

To avoid introducing new things to the ABI, I am suggesting removing gz_error entirely from map.
That way it won't need any prefixing or mangling either, because the map already is the only reason why it gets any external visibility, and that is something it does not need to have.

@mtl1979
Copy link
Copy Markdown
Collaborator Author

mtl1979 commented Jan 12, 2026

Z_INTERNAL has no effect in static builds as linker handles it for shared builds. Static builds also don't use the map file so catch all local doesn't work. Only on Windows exported symbols need to be explicitly marked as such.

@Dead2
Copy link
Copy Markdown
Member

Dead2 commented Jan 12, 2026

Z_INTERNAL has no effect in static builds as linker handles it for shared builds. Static builds also don't use the map file so catch all local doesn't work. Only on Windows exported symbols need to be explicitly marked as such.

In that case static builds won't work anyway, because we have lots of Z_INTERNAL functions that do not get mangled or prefixed.
So that is not a blocker for removing gz_error from the map.

@mtl1979
Copy link
Copy Markdown
Collaborator Author

mtl1979 commented Jan 12, 2026

Z_INTERNAL has no effect in static builds as linker handles it for shared builds. Static builds also don't use the map file so catch all local doesn't work. Only on Windows exported symbols need to be explicitly marked as such.

In that case static builds won't work anyway, because we have lots of Z_INTERNAL functions that do not get mangled. So that is not a blocker for removing gz_error from the map.

The point (of this PR) is to gradually make both shared and static builds work with all options enabled. Removing gz_error or zng_gz_error from the zlib-ng.map file doesn't mean it doesn't need to be mangled for static builds. More symbols we have explicitly marked as local in map files, closer we are getting to actually working build with both symbol prefixing, and linking against both stock zlib and zlib-ng in static build.

@Dead2
Copy link
Copy Markdown
Member

Dead2 commented Jan 12, 2026

The point (of this PR) is to gradually make both shared and static builds work with all options enabled. Removing gz_error or zng_gz_error from the zlib-ng.map file doesn't mean it doesn't need to be mangled for static builds. More symbols we have explicitly marked as local in map files, closer we are getting to actually working build with both symbol prefixing, and linking against both stock zlib and zlib-ng in static build.

I think that is something that should be done in a separate PR, and to avoid ABI churn, either don't PREFIX gz_error in this PR, or remove it from map entirely.

In any case, whether the names need mangling or not for static builds, Z_INTERNAL symbols should not be in the map file. The symbols that need to be marked as local in .map files should be tagged as hidden, not internal. Marking things internal removes them from the symbol table entirely, making the library smaller and enables more optimizations. Adding them to the map file however conflicts with that.

@mtl1979
Copy link
Copy Markdown
Collaborator Author

mtl1979 commented Jan 12, 2026

I think that is something that should be done in a separate PR, and to avoid ABI churn, either don't PREFIX gz_error in this PR, or remove it from map entirely.

I'm not against removing it from the zlib-ng.map file as removing local symbols doesn't break ABI and we don't advertise backwards compatibility in the map file, so we don't need to care about any symbol renames.

The entry was needed for validating this PR, but now I know what had to be done, so I think it's safe to remove.

* We need to mangle symbols in the map file, otherwise none of the symbols are exported
* Fix gz_error name conflict with zlib-ng API
@Dead2 Dead2 changed the title Fix symbol mangling so symbols in shared library are exported correctly Fix symbol mangling and prefix gz_error Jan 13, 2026
@Dead2 Dead2 merged commit 55d456f into zlib-ng:develop Jan 14, 2026
171 of 173 checks passed
@Dead2 Dead2 mentioned this pull request Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants