[llvm-dev] [RFC] Modernize CMake LLVM "Components"/libLLVM Facility
Tom Stellard via llvm-dev
llvm-dev at lists.llvm.org
Mon Jan 4 11:04:09 PST 2021
On 1/3/21 1:49 PM, Stella Laurenzo via llvm-dev 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.
Do you have a proposed list of components yet for LLVM?
> * 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.
>
It sounds like what you are proposing is BUILD_SHARED_LIBS=ON but with
fewer total libraries, is this an accurate summary?
I would prefer for any large change like this that we do not add any net
new configuration options (meaning if we add a new option we should
remove an old one)to LLVM as we already have too many. Would this be
able to replace BUILD_SHARED_LIBS=ON?
- Tom
> *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?
>
> Thanks!
> - Stella
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
More information about the llvm-dev
mailing list