kspalaiologos / bzip3

A better and stronger spiritual successor to BZip2.
GNU Lesser General Public License v3.0
687 stars 38 forks source link

Properly hide private symbols and export public symbols if shared #46

Closed SpaceIm closed 2 years ago

SpaceIm commented 2 years ago

This logic is broken for MinGW static & doesn't support msvc shared: https://github.com/kspalaiologos/bzip3/blob/98f8e5030bc5a7ffa08a5446776ef16abfe8a7ed/include/common.h#L49-L53

Could be improved:

kspalaiologos commented 2 years ago

It's pretty strange that libtool doesn't allow to define separate flags for building static and shared objects, which would make solving this issue with moderate portability way easier.

kspalaiologos commented 2 years ago

i have pushed a fix using libtool export-symbols-regex, which seems to work for non-LTO builds:

% nm -D .libs/libbzip3.so
0000000000004670 T bz3_decode_block
0000000000006210 T bz3_decode_blocks
00000000000014d0 T bz3_encode_block
0000000000005ef0 T bz3_encode_blocks
00000000000014a0 T bz3_free
0000000000001360 T bz3_last_error
00000000000013a0 T bz3_new
0000000000001370 T bz3_strerror
                 U calloc@GLIBC_2.2.5
                 w __cxa_finalize@GLIBC_2.2.5
                 U free@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U malloc@GLIBC_2.2.5
                 U memcpy@GLIBC_2.14
                 U memmove@GLIBC_2.2.5
                 U memset@GLIBC_2.2.5
                 U pthread_create@GLIBC_2.34
                 U pthread_exit@GLIBC_2.2.5
                 U pthread_join@GLIBC_2.34
SpaceIm commented 2 years ago

I would have expected something more portable:

in libbz3.h:

#ifdef bzip3_EXPORTS
#ifdef _WIN32
    #define BZIP3_API __declspec(dllexport)
#else
    #define BZIP3_API __attribute__((visibility("default")))
#endif
#else
    #define BZIP3_API
#endif

and:

I'm not an expert of autotools, we compile bzip3 with CMake in conan package manager because it's too tedious to use autotools with msvc.

kspalaiologos commented 2 years ago

cc: @alerque - I'm not sure how step2 should be performed with our current autotools setup.

the first step can be done by adding -fvisibility=hidden to the compiler flags.

alerque commented 2 years ago

I'm sorry I only have a few short brain waves to spare but I'll try to help. Which step 2 do you mean, the #ifdef _WIN32 bit? And you're looking for something that is defined when either compiling on or for the windows side of things? Or when doing a shared rather than static build?

kspalaiologos commented 2 years ago

define bzip3_EXPORTS (or whatever other definition name you prefer) at compilation time of the shared flavor

- wondering how to disambiguate shared and static builds.

alerque commented 2 years ago

Not a full answer, but research so far before I run off...

The last half or so of this manual page seems to be relevant. The issue I see (if I'm understanding this correctly) is that by default unless ./configured otherwise the autotools build will build both static and shared libraries. You can disable either one (see ./configure --help). The last code snippet on that page suggests how to add a define macro for use when something is enabled. I don't think that helps at all to understand which one is being built at a given moment unless the user has only one mode enabled.

To be continued...

SpaceIm commented 2 years ago

Would it be possible to at least move definitions of PUBLIC_API to libbz3.h, rename it BZIP3_API and put this definition in front of each declaration please?

Something like this in libbz3.h:

#ifndef BZIP3_API
    #define BZIP3_API
#endif

Because I would like to avoid patching bzip3 in conan-center forever. At least with this workaround I can inject BZIP3_API definition with appropriate value at compile time if built as a shared library. It's an ugly workaround but at least we can live with this.

I guess you don't test msvc build, otherwise you would have seen this bug.