[llvm-dev] [RFC] Modernize CMake LLVM "Components"/libLLVM Facility
Mehdi AMINI via llvm-dev
llvm-dev at lists.llvm.org
Sun Jan 3 20:45:43 PST 2021
On Sun, Jan 3, 2021 at 1:50 PM Stella Laurenzo via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> Hi folks, happy new year!
>
> *Proposal:*
>
> - See comments at the top of LLVMComponents.cmake
> <https://github.com/stellaraccident/llvm-project/blob/newcomponents/llvm/cmake/modules/LLVMComponents.cmake>
> in my fork
> <https://github.com/stellaraccident/llvm-project/tree/newcomponents>.
> - Draft phab: https://reviews.llvm.org/D94000
>
>
> *Background:*
> As I've been working on NPCOMP <https://github.com/llvm/mlir-npcomp> trying
> to come up with a release flow for MLIR derived Python projects (see
> py-mlir-release <https://github.com/stellaraccident/mlir-py-release>),
> I've repeatedly run into issues with how the LLVM build system generates
> shared libraries. While the problems have been varied, I pattern match most
> of them to a certain "pragmatic" nature to how components/libLLVM/libMLIR
> have come to be: in my experience, you can fix most individual dynamic
> linkage issues with another work-around, but the need for this tends to be
> rooted in a lack of definition and structure to the libraries themselves,
> causing various kinds of problems and scenarios that don't arise if
> developed to stricter standards. (This isn't a knock on anyone -- I know
> how these things tend to grow. My main observation is that I think we have
> outgrown the ad-hoc nature of shared libraries in the LLVM build now).
>
> I think I'm hitting this because reasonable Python projects and releases
> pre-supposes a robust dynamic linkage story. Also, I use Windows and am
> very aware that LLVM basically does not support dynamic linking on Windows
> -- and cannot without more structure (and in my experience, this structure
> would also benefit the robustness of dynamic linking on the others).
>
> Several of us got together to discuss this in November
> <https://llvm.discourse.group/t/meeting-notes-mlir-build-install-and-shared-libraries/2257>.
> We generally agreed that BUILD_SHARED_LIBS was closer to what we wanted vs
> libLLVM/libMLIR, but the result is really only factored for development
> (i.e. not every add_library should result in a shared object -- the shared
> library surface should mirror public interface boundaries and add_library
> mirrors private boundaries). The primary difference between the two is:
>
> - BUILD_SHARED_LIBS preserves the invariant that every translation
> unit will be "homed" in one library at link time (either .so/.dll or .a)
> and the system will never try to link together shared and static
> dependencies of the same thing (which is what libLLVM/libMLIR do today). It
> turns out that this is merely a good idea on most platforms but is the core
> requirement on native Windows (leaving out mingw, which uses some clever
> and dirty tricks to try to blend the worlds).
> - LLVM_BUILD_LLVM_DYLIB treats libLLVM.so as a "bucket" to throw
> things that might benefit from shared linkage, but end binaries end up also
> needing to link against the static libraries in case if what you want isn't
> in libLLVM.so. When this is done just right, it can work (on Unix) but it
> is very fragile and prone to multiple definition and other linkage issues
> that can be extremely hard to track down.
>
> *What I did:*
>
> 1. Well, first, I tried looking the other way for a few months and
> hoping someone else would fix it :)
> 2. When I started trying to generalize some of the shared library
> handling for MLIR and NPCOMP, I noted that the LLVM_LINK_COMPONENTS (as in
> named groups of things) are in the right direction of having a structure to
> the libraries, and I found that I could actually rebase all of what the
> LLVM_LINK_COMPONENTS was trying to do on the same facility, relegating the
> existing LLVM_LINK_COMPONENTS to a name normalization layer on top of a
> more generic "LLVM Components" facility that enforces stricter layering and
> more control than the old libLLVM.so facility did.
> 3. I rewrote it twice to progressively more modern CMake and was able
> to eliminate all of the ad-hoc dependency tracking in favor of
> straight-forward use of INTERFACE libraries and $<TARGET_PROPERTY>
> generator expressions for selecting static or dynamic component trees based
> on global flags and the presence (or absence) of per-executable
> LLVM_LINK_STATIC properties
> 1. Note that since this is rooted only in CMake features and not
> LLVM macros, out of tree, non-LLVM projects should be able to depend on
> LLVM components in their own targets.
> 4. I hacked up AddLLVM/LLVM-Build/LLVM-Config to (mostly) use the new
> facility (leaving out a few things that can be fixed but aren't conceptual
> issues), applied a bunch of fixes to the tree that were revealed by
> stricter checks and got all related tests passing for LLVM and MLIR (on X86
> -- some mechanical changes need to be made to other targets) for both
> dynamic and static builds.
>
> *What I'd like to do:*
>
> - Get some consensus that we'd like to improve things in this area and
> that the approach I'm taking makes sense. I can do a lot of the work, but I
> don't want to waste my time, and this stuff is fragile if we keep it in an
> intermediate state for too long (I'm already paying this price downstream).
> - Land LLVMComponents.cmake
> <https://github.com/stellaraccident/llvm-project/blob/newcomponents/llvm/cmake/modules/LLVMComponents.cmake>
> as the basis of the new facility.
> - Finish implementing the "Redirection" feature that would allow us to
> emulate an aggregate libLLVM as it is today.
> - Start pre-staging the various stricter constraints to the build tree
> that will be needed to swap AddLLVM to use the new facility.
> - Rewrite component-related AddLLVM/LLVM-Build/LLVM-Config bits in a
> more principled way to use the new facility (or remove features entirely
> that are no longer needed) -- what I did in the above patch was just a
> minimal amount of working around for a POC.
> - Agree on whether we should try to have the two co-exist for a time
> or do a more clean break with the old.
> - Start applying the facility to downstream projects like MLIR and
> NPCOMP.
>
> *What I would need:*
>
> - Help, testing and expertise. I am reasonably confident in my
> understanding of how to make shared libraries work and how to use CMake,
> but the legacy in LLVM here is deep -- I likely pattern matched some old
> features as no longer needed when they actually are (I am not clear at all
> on how much of LLVM-Config is still relevant).
> - Pointers to who the stakeholders are that I should be coordinating
> with.
>
> Comments?
>
Looks great! In particular it is interesting to see how more modern CMake
features could replace some of the custom-LLVM CMake macros that are likely
almost a decade old now.
One thing I wonder about trying to see BUILD_SHARED_LIBS as some desirable
for a production environment: I seem to remember that there were
non-trivial performance regression when using many .so instead of a single
libLLVM.so (even a single libLLVM.so was showing a measurable performance
impact for clang IIRC).
--
Mehdi
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210103/424875ca/attachment.html>
More information about the llvm-dev
mailing list