[PATCH] D89177: [cmake] Add support for multiple distributions

Shoaib Meenai via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 14 15:40:20 PDT 2020


smeenai added a subscriber: ldionne.
smeenai added a comment.

In D89177#2326875 <https://reviews.llvm.org/D89177#2326875>, @phosek wrote:

> In D89177#2326832 <https://reviews.llvm.org/D89177#2326832>, @smeenai wrote:
>
>> In D89177#2325566 <https://reviews.llvm.org/D89177#2325566>, @phosek wrote:
>>
>>> We've already considered introducing a similar mechanism so thank you for working on this! There's one issue that I haven't figured out how to resolve and I'd be interested in your thoughts: building executables and libraries in the most optimal may require incompatible flags. For example, when building a shared library you have to use `-fPIC` but for executables that's suboptimal; similarly, when building executables you may want to use LTO but if you also want to create a distribution that contains static libraries, that's a problem because those will contain bitcode. So far our solution has been to simply do multiple builds with different flags (in GN this can be done in a single build by leveraging the "toolchain" concept that also allows sharing as much work as possible, but I haven't figured out how to do anything like that in CMake).
>>
>> Good question. We need something similar as well, where some clients of the libraries want them built with RTTI (because their programs rely on RTTI and you can get link errors when linking them against non-RTTI LLVM libraries), but we don't wanna build the executables with RTTI because of the size increases.
>
> We recently ran into this as well where we need RTTI for LLVM libraries but don't want to enable it for the toolchain.
>
>> I don't know of any way to do this in CMake other than just configuring multiple times with the different flags, like you said. Maybe we could implement some logic for that in the build system, but I'm not sure if it's worth it. (I'm wondering if the Ninja multi-config generator added in CMake 3.17 could be useful for this, although I haven't played around with that at all yet.) I do recognize it limits the usefulness of this approach quite a bit (since if you're doing separate configurations you can just do different `LLVM_DISTRIBUTION_COMPONENT` settings), but I'm hoping it can still be valuable for simpler scenarios.
>
> One idea I had would be to eliminate the use of global variables like `CMAKE_C_FLAGS` and `CMAKE_CXX_FLAGS` and always set these via `target_compile_options` (which is something we should do in any case to move towards more modern CMake); since we always use functions like `add_llvm_component_library` to create targets in LLVM, we could then have these create multiple targets that would differ in flags like `-fPIC` or `-frtti` and set up dependencies among these appropriately. It means you'd have to build files multiple times (I don't think there's any way around that) but you'd save time on things like tablegen.

Yeah, we should definitely be moving away from global flag manipulation (and I know @ldionne has been doing a bunch of cleanups for that in libc++). Being able to have as much commonality as possible would be nice, although CMake seems to be more in the "different configurations/build types for different build settings" camp.

Reading up on the Ninja multi-config generator more, it seems pretty well suited to handling things like PIC vs. non-PIC and LTO vs. non-LTO (although I haven't thought a lot about how those configs would interact with the multi-stage bootstrapping setups). RTTI vs. non-RTTI is more complicated (see my previous comment), but should be achievable by tweaking how LLVM's build system manipulates those flags. (Strawman proposal: have `LLVM_ENABLE_RTTI` accept a `default` argument in addition to the regular booleans to denote that you want LLVM to respect your config's flag settings for RTTI instead of trying to enforce its own.)

>> Out of curiosity, with GN, how would you specify that you want binaries to be built with one toolchain (e.g. LTO and non-PIC) and libraries with another (e.g. non-LTO and PIC)?
>
> In GN there's no global concept of tools like `CC` or `LD`, instead these are scoped inside a `toolchain` which in GN is a first class concept, and dependencies can be parametrized by toolchains (for example you can have `deps = [ "//path/to/dependency(//path/to/toolchain)" ]`. These toolchains can be also parametrized and templated. A common use case is to have a variety of toolchains that have the same tools but differ in flags like `-fPIC`. In Ninja this is represented as subninjas where each child Ninja file defines its own set of rules.
>
> You can see an example of this even in LLVM GN build where we define a set of toolchains in https://github.com/llvm/llvm-project/blob/1687a8d83b702332c4aae4f2a95d27c16688418d/llvm/utils/gn/build/toolchain/BUILD.gn#L179 and then use them to built runtimes in https://github.com/llvm/llvm-project/blob/1687a8d83b702332c4aae4f2a95d27c16688418d/llvm/utils/gn/secondary/compiler-rt/BUILD.gn which is an (more efficient) equivalent of the runtimes build.

GN's toolchain system is really cool :) I was wondering how you'd tell GN that you want all your binaries to be built with one toolchain and all your libraries to be built with another one, but I found https://github.com/llvm/llvm-project/blob/master/llvm/utils/gn/build/BUILDCONFIG.gn, which I think answers that question.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89177/new/

https://reviews.llvm.org/D89177



More information about the cfe-commits mailing list