Adding additional instantiations to the dylib isn't actually an ABI break as long as programs targeting an older dylib don't start to depend on them. Making additional instantiations a matter of availability allows us to add them without an ABI break.
Details
- Reviewers
ldionne Mordante - Group Reviewers
Restricted Project - Commits
- rGc66d0b019a9e: [libc++] Recategorize additional instantiations in the dylib as availability…
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Nice! I don't know why we didn't do those using availability in the first place, it seems strictly better.
libcxx/include/__availability | ||
---|---|---|
180 | I would turn these conditions around instead and use HAS_NO_XXX like all the other availability macros. | |
181 | This macro needs a separate comment. | |
338 | Let's add an entry here for _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_KEY_FUNCTION. Those are the macros you should check to determine that the dylib *did not yet* contain the key function: defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120000 defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000 defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000 defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000 | |
libcxx/include/__config | ||
187–192 | This needs to be translated to the availability, or it'll fail on FreeBSD. FreeBSD doesn't currently enable availability markup, but that is probably needed as a pre-requisite. We could start by unconditionally pretending that all the _LIBCPP_AVAILABILITY_XXXXXXXX are enabled on FreeBSD, which would be equivalent to what they have today. |
I would like to split the good-what-message part of this change into its own patch, since it's significantly different from the other changes. But apart from that, this change makes sense to me.
libcxx/include/__availability | ||
---|---|---|
183 | This comment should probably be copied from the original one? | |
371 | First, this doesn't match the macro above (which is _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE_AND_KEY_FUNCTION). Second, I would like us to split the good-what-message part of this change into its own patch since it is more tricky to get right, and in fact it *is* an ABI break (it might just be one that we can do in case it only affects arm64e). | |
libcxx/include/__config | ||
187–192 | I think I meant AIX here. The comment makes sense if you re-read and say AIX in your head. |
libcxx/include/__availability | ||
---|---|---|
1 | The commit message should be updated to be specific to the additional iostream instantiations. | |
367–372 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120000) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000) || \ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000) || \ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000) # define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 # endif This would be more consistent with the other availability macros. If we want to invert the logic and instead use _LIBCPP_AVAILABILITY_HAS_FOO, let's do it for all the macros in a separate patch (I think it would be a reasonable change since it would avoid breaking vendors when adding new availability macros). |
Can you rebase to poke the CI? Also, please remove the reference to the radar from the commit message, since the radar was about bad_function_call (which we will handle separately).
Other than that, LGTM.
Requesting changes since I'd like to discuss the latest changes to the patch during our next 1:1
libcxx/include/__availability | ||
---|---|---|
185 | Here, let's do this instead: // Enable additional explicit instantiations of iostreams components. This // reduces the number of weak definitions generated in programs that use // iostreams by providing a single strong definition in the shared library. // // TODO: Enable additional explicit instantiations on GCC once it supports // exclude_from_explicit_instantiation, or once libc++ doesn't use the attribute anymore. // TODO: Enable them on Windows once https://llvm.org/PR41018 has been fixed. #if defined(_LIBCPP_COMPILER_GCC) || defined(_WIN32) # define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 #else // # define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 #endif Then you can remove the workarounds in libcxx/include/sstream. |
I guess it doesn't anymore for Windows or GCC. That definitely wasn't intended, but I'm not sure that's such a bad thing, since we ran into multiple bugs when trying to enable it in ABIv1 there.
This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?
I’ve had some issues building stage2 builds on my machine, so I’ve struggled reproducing it locally. If you’re certain the new include should be there regardless, I’d say the fastest way to learn whether it fixes this particular problem would be to commit it and wait for CI to build, tbh. Otherwise I’ll give it another go in the morning.
I've committed it already, since it's definitely missing. I wasn't sure whether the bot was building from trunk or not.
Hmm, unfortunately it seems like the issue still persists. This build should contain your fix for both the stage1 and stage2 builds: https://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/7627/console. I still haven't been able to do a stage2 build locally to replicate.
The commit message should be updated to be specific to the additional iostream instantiations.