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

fix: missing -DPROTOBUF_USE_DLLS in pkg-config #12700

Conversation

coryan
Copy link
Contributor

@coryan coryan commented May 6, 2023

When the protobuf libraries have been compiled as shared libraries the users of the library need to add -DPROTOBUF_USE_DLLS to their build line. Otherwise some symbols are missing.

Fixes #12699

FWIW, I am not sure this is an ideal fix. It may be better to fix the headers such that no macros change the ABI.

When the protobuf libraries have been compiled as shared libraries the
users of the library need to add `-DPROTOBUF_USE_DLLS` to their build
line. Otherwise some symbols are missing.
@coryan coryan marked this pull request as ready for review May 6, 2023 21:59
@coryan coryan requested a review from a team as a code owner May 6, 2023 21:59
@coryan coryan requested review from haberman and removed request for a team May 6, 2023 21:59
@fowles fowles added the 🅰️ safe for tests Mark a commit as safe to run presubmits over label May 7, 2023
@github-actions github-actions bot removed the 🅰️ safe for tests Mark a commit as safe to run presubmits over label May 7, 2023
@copybara-service copybara-service bot closed this in f86008a May 7, 2023
@coryan coryan deleted the fix-define-protobuf-use-dlls-in-pkg-config-file branch May 7, 2023 16:31
@Romain-Geissler-1A
Copy link
Contributor

Hi,

I don't understand actually, why does PROTOBUF_USE_DLLS has an influence on ABI ? For me these kind of macro shall just influence wether or not symbols are exported, and not the underlying code. So shouldn't we instead update the arena/reflection_mode code instead to NOT depend on PROTOBUF_USE_DLLS at all ? Actually I don't see (on Linux at least, but it seems PROTOBUF_USE_DLLS has historically be a MSVC specific thing) why the could would be different between static lib and shared lib.

Cheers,
Romain

@coryan
Copy link
Contributor Author

coryan commented Jun 5, 2023

I don't understand actually, why does PROTOBUF_USE_DLLS has an influence on ABI ? For me these kind of macro shall just influence wether or not symbols are exported, and not the underlying code. So shouldn't we instead update the arena/reflection_mode code instead to NOT depend on PROTOBUF_USE_DLLS at all ? Actually I don't see (on Linux at least, but it seems PROTOBUF_USE_DLLS has historically be a MSVC specific thing) why the could would be different between static lib and shared lib.

You may want to open a bug asking these questions. A comment in a PR is likely to get lost. Your questions make sense to me, but I have limited time to improve Protobuf, I just need it to work.

@Romain-Geissler-1A
Copy link
Contributor

@coryan Ok, actually I went a bit further by trying to understand why we have this, and proposing a "fix" in #12983

copybara-service bot pushed a commit that referenced this pull request Jun 6, 2023
…orms (#12983)

Hi,

It seems that until last year, the logic behind `PROTOBUF_USE_DLLS` was for Windows (MSCV) only. It was changed to all platforms here in 5a0887f

Last month, the generated pkg config files were updated to reflect the protobuf build-time value of `PROTOBUF_USE_DLLS` as it was indeed noted that it changes the ABI. This was done in #12700 In the commit message it is mentionned that most likely we shall rather have a stable ABI.

Finally in #12746 which at some point mentions https://issuetracker.google.com/issues/283987730#comment7 where a Google employee hits the linker issue:
```
undefined reference to `google::protobuf::internal::ThreadSafeArena::thread_cache_'
```
which denotes a mix of some .o or libs built `PROTOBUF_USE_DLLS` defined and some others build with `PROTOBUF_USE_DLLS` undefined, resulting in ABI incompatibilities.

I also hit this issue while trying to include protobuf in a corporate environment using it's own proprietary build system in which it is expected that .a and .so use a compatible ABI.

From my own understanding, ideally we should always use `thread_local` variables, but experience has shown that:
 - old iOS (iOS < 9) didn't seem to accept `thread_local`, leading to the `GOOGLE_PROTOBUF_NO_THREADLOCAL` macro later renamed `PROTOBUF_NO_THREADLOCAL` which allowed to disable this, but it is not set anywhere in the protobuf code base. Also I doubt you still want to support such old iOS now, so maybe you should consider removing all `PROTOBUF_NO_THREADLOCAL` related code paths (this pull request doesn't do this).
  - MSVC's DLL interface doesn't seem to accept exporting thread local variables (at least from what I understood, I know absolutely nothing about the Windows ecosystem), yet we can "hide" a thread local variable in a static function using a thread local variable. However in that case the access to TLS variable is not inlined, leading to worse performances, this hack shall be done only for Windows (actually when using MSVC) *AND* we build a shared library.
  - In all other cases, a classical `thread_local` shall be used, no matter if we build a static or a shared library. In particular on Linux which I guess is the target Google cares the more about for its own production. This pull request achieves this.

Am I right in my conclusion ?

Closes #12983

COPYBARA_INTEGRATE_REVIEW=#12983 from Romain-Geissler-1A:stable-abi-use-dll-non-windows dc23ff5
PiperOrigin-RevId: 538230923
fowles pushed a commit to fowles/protobuf that referenced this pull request Jun 7, 2023
…orms (protocolbuffers#12983)

Hi,

It seems that until last year, the logic behind `PROTOBUF_USE_DLLS` was for Windows (MSCV) only. It was changed to all platforms here in protocolbuffers@5a0887f

Last month, the generated pkg config files were updated to reflect the protobuf build-time value of `PROTOBUF_USE_DLLS` as it was indeed noted that it changes the ABI. This was done in protocolbuffers#12700 In the commit message it is mentionned that most likely we shall rather have a stable ABI.

Finally in protocolbuffers#12746 which at some point mentions https://issuetracker.google.com/issues/283987730#comment7 where a Google employee hits the linker issue:
```
undefined reference to `google::protobuf::internal::ThreadSafeArena::thread_cache_'
```
which denotes a mix of some .o or libs built `PROTOBUF_USE_DLLS` defined and some others build with `PROTOBUF_USE_DLLS` undefined, resulting in ABI incompatibilities.

I also hit this issue while trying to include protobuf in a corporate environment using it's own proprietary build system in which it is expected that .a and .so use a compatible ABI.

From my own understanding, ideally we should always use `thread_local` variables, but experience has shown that:
 - old iOS (iOS < 9) didn't seem to accept `thread_local`, leading to the `GOOGLE_PROTOBUF_NO_THREADLOCAL` macro later renamed `PROTOBUF_NO_THREADLOCAL` which allowed to disable this, but it is not set anywhere in the protobuf code base. Also I doubt you still want to support such old iOS now, so maybe you should consider removing all `PROTOBUF_NO_THREADLOCAL` related code paths (this pull request doesn't do this).
  - MSVC's DLL interface doesn't seem to accept exporting thread local variables (at least from what I understood, I know absolutely nothing about the Windows ecosystem), yet we can "hide" a thread local variable in a static function using a thread local variable. However in that case the access to TLS variable is not inlined, leading to worse performances, this hack shall be done only for Windows (actually when using MSVC) *AND* we build a shared library.
  - In all other cases, a classical `thread_local` shall be used, no matter if we build a static or a shared library. In particular on Linux which I guess is the target Google cares the more about for its own production. This pull request achieves this.

Am I right in my conclusion ?

Closes protocolbuffers#12983

COPYBARA_INTEGRATE_REVIEW=protocolbuffers#12983 from Romain-Geissler-1A:stable-abi-use-dll-non-windows dc23ff5
PiperOrigin-RevId: 538230923
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.

The pkg-config files should define PROTOBUF_USE_DLLS if the libraries are shared
3 participants