Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static builds and exported symbols #376

Open
pictview opened this issue Jun 26, 2024 · 2 comments
Open

Static builds and exported symbols #376

pictview opened this issue Jun 26, 2024 · 2 comments

Comments

@pictview
Copy link

pictview commented Jun 26, 2024

I think there is no need to export all symbols when building a static lib with clang. Hence I suggest to change the following
#elif defined(_GNUC_)
#  define LIBDEFLATE_EXPORT_SYM _attribute_((visibility("default")))
#else
#  define LIBDEFLATE_EXPORT_SYM
#endif
to something like
#elif defined(_GNUC_) || defined(_clang_)
#  if defined(LIBDEFLATE_DLL)
#    define LIBDEFLATE_EXPORT_SYM _attribute_((visibility("default")))
#  else
#    define LIBDEFLATE_EXPORT_SYM _attribute_((visibility("hidden")))
#  endif
#else
#  define LIBDEFLATE_EXPORT_SYM
#endif

maybe then LIBDEFLATE_DLL should be renamed to something like LIBDEFLATE_SHARED.

@ebiggers
Copy link
Owner

ebiggers commented Jul 3, 2024

So you'd like __attribute__((visibility("hidden"))) to be used when building a static library. Why? I didn't think it made a difference for static libraries.

@pictview
Copy link
Author

pictview commented Jul 3, 2024

It makes two differences:

  1. hidden symbols make the binary somewhat smaller
  2. more importantly, there can be clashes on some systems when multiple binaries export symbols of the same name. This can lead to crashes if the two symbols come from different library versions and expect different arguments. For example, on Windows, each module .EXE/.DLL strictly defines the name of the .DLL from which the imported symbol should come. If the symbols actually resides in the same .EXE/.DLL, then it is not imported, but the symbol in the same .EXE/.DLL is called.. However, it is very different for example on macOS. If two dylibs export a symbol of the same name, it is undefined which is used at runtime. Even when module A.dylib exports a symbol S and wants to use it, it may actually happen that the OS decides to pair the import of S from A.dylib with the export of the symbol S from B.dylib, i.e. A.dylib will actually call the implementation of S in B.dylib. Under which circumstances can a single process contain 2 dylibs exporting the same symbol but from different versions of the same static library? Think of plugins for e.g. Adobe products coming from different vendors.

zachlewis added a commit to zachlewis/libdeflate that referenced this issue Nov 15, 2024
This PR implements @pictview's suggestion from ebiggers#376 to hide symbols when building a static library.
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

No branches or pull requests

2 participants