Rationale for removing versioned libclang? --> Middle ground to keep it behind option?

Hi all

It might be quite late in the process for LLVM 15, but I was wondering if there was some more discussion context for the revertion of the versioned libclang output that got added in ⚙ D105527 libclang.so: Make SONAME independent from LLVM version and reverted in ⚙ D129160 libclang.so: Make SONAME the same as LLVM version without much further discussion (AFAICS).[1] While I reviewed the latter PR at the time, I did not really understand (nor question) the reasons for the choice itself.

Still it’s perhaps a change that’s worthy of a wider audience (if only in terms of visibility). In particular, @isuruf (a very experienced collaborator of conda-forge[2]) asked in the PR:

@MaskRay just responded

I’m wondering if this is not more a social problem (e.g. the original change was not very clearly communicated, leading to people stumbling over the apparently wrong SOVERSION).

But even assuming that the default build needs to produce a SOVERSION equal to LLVM major, I’m wondering if it wouldn’t be possible to provide a CMake option to choose to use CLANG_SOVERSION.

It would be great to have this information, even if it’s not the default, because the ABI-compat level is essentially impossible for us to tell from afar, but using an already-defined constant is easy.

Thanks
H.


  1. I’m in the awkward position that I had raised an issue about this during the LLVM 14 rc-phase, but more because it wasn’t clearly documented at the time, rather than being bad. ↩︎

  2. Isuru and I work on integrating the LLVM stack into conda-forge, a python-centric (but not only), cross-platform package manager (or perhaps quasi-distro). We are constricted to publicly available CI, and some big packages (e.g. QT) do not fit into the available limits e.g. on Azure Pipelines. ↩︎

1 Like

Most of it was discussed in this thread I think: RFC: Only change libclang.so SONAME when the ABI changes

Ah I posted that thread a bit quickly. I see now what you mean with it being a bit light on details. Yeah I think it would be good for people that want to keep the current status quo to chime in and let us know what they think.

Yeah, most of that thread is in favour of doing that AFAICT. Thanks for the reference nonetheless, I posted a short comment there as well.

Here are all the bugs that were filed when we made the change to have stable soname for LLVM14:

The two main reasons that I can see to undo the change were:

  1. It was confusing people and breaking build systems to have libclang.so.13 instead of libclang.so.$VERSION_NUMBER.

  2. There’s no way to know which version of LLVM libclang.so is linked against, so if an application wants to link against libLLVM.so and libclang.so, there is a risk have loading two different versions of libLLVM.so at the same time (one for the application and one for libclang.so).

Thanks for the quick response. I understand the messaging problem, i.e. that it looks like a bug in the build-system.

What do you think about the “middle ground” proposal to have it available behind an option (and perhaps an altered lib name - that wouldn’t matter in the cases where it’s relevant)?

@tstellar, I agree that it was confusing and certainly a bit unfortunate that we got stuck at 13, but I think the change was well reasoned and going back now is only going to add to the confusion.

Prior to 14.0.0 this was certainly a valid concern, but now we’ve had an entire release cycle with split versions and the packaging work to handle this properly has been done. I don’t think it helps to revert this now.

1 Like

@tstellar @tobiashieta
Would you consider a revert of ⚙ D129160 libclang.so: Make SONAME the same as LLVM version + the introduction of a CMake switch?

I chatted to Tom about this yesterday. We are open to reverting it if we think it will go over better this time. But we didn’t think a flag is a good idea - the risk of confusion with two different versioning systems is probably high.

1 Like

I know the change made 14 unusable for me as we kept multiple versions of the LLVM and Clang libraries in a visible in a single tool tree with logic to ensure compiles of a given context always reproduce the exact same object files. The reuse of the 13 so broke stuff when trying to install as it mixed up the dependent libraries used such the llvm libraries. If this is reinstated a canonical way to set the so number to match the major version would be useful to have.

Could you explain this in more detail? Since libclang.so has a pretty strict ABI guarantee, you should generally just be able to drop in a new version.¹ And to my knowledge it can’t generate object files at all, it’s purely a frontend. It’s also not used by the compiler or any tool other than c-index-test, which should probably not be used productively.

Possibly you want an IDE to pick the libclang.so for the compiler that you’re using? But then you can’t have multiple versions coexist because they would conflict (unless there is some weird trick with RTLD_LOCAL that I don’t know about). You would have to fire up separate processes using the different library versions.

Edit: I think I got it. You’re simply saying that you can’t put the files in a common tree, which is certainly true because the libclang.so.13 links conflict between 13 and 14. Here’s some ideas:

  • Just don’t build or ship it. It’s not used for compiling, only for IDEs and similar tools.
  • Do whatever you’re doing with the libclang.so link. This also conflicts between major versions.
  • If you have some packaging system, package the library separate from the remainder and have LLVM 14’s libclang.so.13 supersede LLVM 13’s. (That’s what we’re doing and likely most other Linux distros—in whichever way they can supersede stuff.)

¹ To be fair, there are issues with Clang’s placement of builtin headers, but that’s an issue even for new patch-level versions. A solution for that would likely also work with major version updates.

What’s the status here? LLVM 15.x release status says we have <24h left for changes going into LLVM 15, so such a revert would be quite urgent now (I’d understand the choice not to gate behind a variable BTW, but it’d b a pity to throw away all the work that had gone into this, and the benefits we’d be foregoing)

Hi!

It would be nice if we could solve this before 15.0.0-final since otherwise we have to wait for 16.x. As I see it we have a few options:

  1. status quo - don’t change anything and keep the SOVERSION == LLVM release version
  2. change it to mean ABI breaks as it’s “supposed” to mean. We probably should have a new version instead of 14 in that case to avoid confusion
  3. make the soversion configurable with the default being a ABI stable number or the version number

Please give feedback so that we can close this issue in the coming two weeks.

If we don’t solve it before -rc3 I am still happy to include it and maybe do a rc4 if we have to. we just need to commit to a solution.

1 Like

Ha, seems we were pretty much simultaneous in thinking about this. :upside_down_face:

Comments:

  1. “Status quo” is a bit fuzzy because there’s at least two: last released version (!=) and tip of tree (==)
  2. What do you mean by “as it’s ‘supposed’ to mean”? AFAIU increment-for-ABI-breaks was already the status as of LLVM 14?

Assuming I’m not overlooking something, I’d prefer 2b. (keep status as of LLVM 14, i.e. SOVERSION=13, increment it for ABI breaks), but could happily live with 3. and would like to avoid 1. if possible.

Thanks for giving this such attention!

I am leaning towards having a option actually - just to not sit this one out for another version, it would also be very low-risk. I think we should make it obvious that the option is temporary and it will be removed in a future release.

What do you think @h-vetinari - could you prepare such patch?

I started looking into this. It’s a bit confusing to me because there already exists an option called LIBCLANG_LIBARY_VERSION which seems like it should control exactly that.

Assuming we still want to add a single option, it’d IMO look something like

# in clang/CMakeLists.txt
option(CLANG_FORCE_MATCHING_LIBCLANG_SOVERSION
  "Force the SOVERSION of libclang to be equal to CLANG_MAJOR" OFF)

# in clang/tools/libclang/CMakeLists.txt
if(NOT CLANG_FORCE_MATCHING_LIBCLANG_VERSION)
  # renamed from previous, less-than-ideal variable name CLANG_SONAME
  set(LIBCLANG_SOVERSION 13)
else()
  set(LIBCLANG_SOVERSION ${CLANG_VERSION_MAJOR})
endif()

if(LIBCLANG_SOVERSION != LIBCLANG_LIBARY_VERSION)
  # error to avoid inconsistent options;
  # harmonization of the two variables can happen for clang 16
endif()

WDYT?

Hmm - if it there is already an option I wonder if that would be enough? But otherwise it looks fine - but I think maybe we should have a warning if it’s enabled and warn about deprecation.

Well, that option did not affect the linker script[1], and didn’t help people from getting tripped up by this. It also somewhat complicates the respective build scripts because one would have to pass the version to some cmake invocation (which obviously changes from version to version, and integrators would prefer not to touch those scripts as much as possible), rather than a simple boolean switch which doesn’t need to be changed.

How about adding the revert + boolean option for LLVM 15.0.0-rc3, and figuring out a more comprehensive clean-up (incl. deprecations) later, with backports as reasonable?


  1. in the current implementation ↩︎

Yep that seems like a great plan so we don’t delay the release that much.