LLVMExports.cmake build/install tree mystery differences

I am trying to create a distribution of LLVM library binaries along with the necessary CMake support libraries so that another CMake-based project can link against those libraries. It seems as though somewhere between the version in the build tree and the one in the install tree, information about crucial LLVM libraries is stripped from LLVMExports.cmake. For example, the string LLVMSupport doesn’t appear anywhere in the installed edition of this file. I can’t for the life of me figure out what controls which libraries end up listed in the installed edition. It looks like just LTO in my case. That /is/ included in LLVM_DISTRIBUTION_COMPONENTS, but adding support there has no effect. Can someone help? My build procedure on Windows is here, FWIW.

Thanks!

We have umbrella llvm-libraries (and *-libraries for other subprojects, e.g. clang-libraries) that you can add to your LLVM_DISTRIBUTION_COMPONENTS to include all the libraries, which is the easiest thing to do for this. Adding individual libraries should also have worked though.

This might just be a typo, but I noticed you said support in your post, whereas the library target name is LLVMSupport, and that’s also how it should be spelled in LLVM_DISTRIBUTION_COMPONENTS. The build should have actually given you an error if you included a non-existent target in LLVM_DISTRIBUTION_COMPONENTS; maybe your change isn’t being propagated somehow?

This might just be a typo, but I noticed you said support in your post, whereas the library target name is LLVMSupport , and that’s also how it should be spelled in LLVM_DISTRIBUTION_COMPONENTS .

After looking at the actual behavior when I passed support I tried it the other way and it made no difference. In order to get an installation usable by cmake I have had to not set LLVM_DISTRIBUTION_COMPONENTS at all.

I hope somebody realizes how confusing it is that

  • There is a concept of named components (which presumably correspond to groups of libraries) that are passed into to llvm_map_components_to_lib_names,
  • But I am supposed to fill up a variable called LLVM_DISTRIBUTION_COMPONENTS with library names and not component names

?

The implication of the name LLVM_DISTRIBUTION_COMPONENTS is that it would install the listed components along with any dependencies. If it’s going to just take the list of names quite literally I’d have expected LLVM_DISTRIBUTION_TARGETS.

I agree that LLVM_DISTRIBUTION_TARGETS would have been a better name. I’m not sure how much appetite there’d be to change it at this point, although I suppose you could have two names. @beanz @phosek what do you think?

Just to clarify, how exactly were you passing support to LLVM_DISTRIBUTION_COMPONENTS? If it was changing your cache file after you’d already configured, did you clean your build directory afterwards (since CMake doesn’t do any cache invalidation)? As far as I can see, support isn’t a valid target name, and you should have gotten a configuration error if it were part of LLVM_DISTRIBUTION_COMPONENTS, which makes me suspect that your changes to that variable aren’t actually getting propagated to the build somehow.

IMO, changing the name of a build setting would be very disruptive. Which isn’t to say we can’t or shouldn’t consider doing it in some cases, but the justification should be strong.

I think LLVM_DISTRIBUTION_TARGETS is probably not a great alternative name, because there are specific requirements for a target to be valid as a component of a distribution. I do agree that the word “component” is overloaded in the build system and doesn’t have a clear meaning, which probably lends to confusion here.

There are significant expected differences between the build-tree and install-tree in the export files. I think @compnerd and @gottesmm have a lot of experience in those areas from the Swift build system.

1 Like

This function may be of interest if the rename happens. It may even be enough to enable the rename to go ahead :wink: .

IMO LLVM_DISTRIBUTION_TARGETS works really well if you introduce the first-class idea of a “distributable target” that fulfills those specific requirements.

That said, if I correctly understand the meaning of “component,” selecting individual targets is a poor interface anyway since many of them could not work without the rest of the targets in their component (and their transitive dependencies). It takes so long to build and test an LLVM build (especially a cross-build) that experimenting with different sets of targets to get it right is simply infeasible and I think almost anyone will—as I did—fail to get it right, eventually give up, and go for a full install… after wasting many days. So I would instead suggest this: change the meaning of this variable so that component names are accepted, and so that any transitive dependency targets are collected into the distribution. To avoid breaking existing code, you can still accept target names, which can retain their current meaning.

Component and target names don’t seem to overlap, but if they did in some case I would prefer to interpret the name as a component. IMO it’s highly unlikely that favoring interpretation as a component would grow any distribution that currently works, since in principle one needs all the dependencies anyway.

I don’t remember whether I cleaned, sadly. I changed it in the contents of my “initial cache file” (-C argument to cmake). But I admit I’m not 100% clear on which changes require cleaning, which require throwing out the cache file, etc., and I may have messed that up.

Yeah, if you change the initial CMake cache file, CMake doesn’t pick up on it automatically. You have to explicitly rerun CMake with the -C argument re-passed, and also either delete the cache entry from CMakeCache.txt or change your cache file temporarily to pass FORCE to the set(CACHE ...) call to make the cache be updated. Normally, when I’m experimenting, I just edit CMakeCache.txt values directly, and propagate the changes back to my initial cache file and test with a clean build when I’ve figured out what works.

Thanks! Is there a place I can find the list of magic (and ordinary) names that are accepted here? Is there a place where I can read about what it means to build or install the distribution as opposed to ordinay building/installing? I feel like I’m stumbling around in the dark here…

Building a Distribution of LLVM — LLVM 19.0.0git documentation is the best documentation we have for this, though it could be more explicit about covering things like the umbrella library targets.

Well, I am starting to think a distribution might not be what I want. I set LLVM_DISTRIBUTION_COMPONENTS="llvm-libraries;lld;llvm-config" and got all those parts but no .cmake files (such as LLVMConfig.cmake) that I can use to work with the result. What am I missing?

You need to add cmake-exports (and likely clang-cmake-exports and lld-cmake-exports) to LLVM_DISTRIBUTION_COMPONENTS to get the CMake files to be included.

Thanks! I am not currently packaging clang or its libraries; I’m trying to make a package of llvm libraries for language development, so I’m assuming clang (and thus clang-cmake-exports) should not be needed(?)

Yup, that’s correct.

…and I’m also missing all the header files. I’m going to crawl into the source, but if someone could tell me explicitly what’s else is needed it would be much appreciated.

I think you need this:
llvm-headers

2 Likes

Nearly there! One last ingredient for my debug builds: I think I need the source files. At least, my debugger is only showing me disassembly.

Hmm, I don’t think we have any CMake target to copy over the source files? At least I’m not aware of any.

I’m sure the thinking is, if you are trying to debug LLVM, you have built it yourself and have a source tree already. Distributing a debug build doesn’t really make that much sense.