The LLVM project publishes prebuilt apt packages. Client projects can easily install a release build of version X via
apt-get install llvm-X-dev and call
find_package(LLVM) from CMake. The mechanism worked well so far, but it broke with LLVM 9, released in Sepember 2019, where the CMake configuration fails with an error message like this:
CMake Error at /usr/lib/llvm-9/lib/cmake/llvm/LLVMExports.cmake:1323 (message): The imported target "yaml-bench" references the file "/usr/lib/llvm-9/bin/yaml-bench" but this file does not exist. Possible reasons include: * The file was deleted, renamed, or moved to another location. * An install or uninstall procedure did not complete successfully. * The installation package was faulty and contained "/usr/lib/llvm-9/lib/cmake/llvm/LLVMExports.cmake" but not all the files it references.
It’s very very unlikely you actually need
yaml-bench. If you have the necessary privileges, you may simply
touch /usr/lib/llvm-9/bin/yaml-bench to put in an empty dummy file. It’s the workaround I choose in my repro.
In LLVM jargon
yaml-bench is a utility, which means it’s not supposed to be used directly by library clients, but instead it’s required by LLVM itself, i.e. for benchmarking. In the apt packages we have currently, benchmarking isn’t fitting well:
- llvm-9 provides toolchain executables and libraries. This is what users want to install.
- llvm-9-dev provides libraries and headers. Library clients would use this package to develop applications that use LLVM.
- llvm-9-tools provides tools for testing LLVM. If you want to run the LLVM tests yourself or you want to use its test infrastructure for your on project, you need this in addition to llvm-9-dev.
A simple solution for package managers would be to extend the purpose of the tools package to benchmarking and add
yaml-bench there. But why does llvm-9-dev depend on llvm-9-tools in the first place?
In order to allow client projects to reference the package content from their build scripts, CMake offers a target export mechanism. From the build-system’s point of view, the package content is what is commonly called install-tree (as compared to source-tree and build-tree). It is populated from the stripped build output after the build has finished and tests succeeded. It appears reasonable that everything that exists in the install-tree should also be exported and thus be accessible to client projects. Up to version 8.0 LLVM’s utility targets have not been exported, neither from the build-tree nor from the install-tree. During the 9.0 cycle, however, this became interesting for other sub-projects, i.e. LLDB. It resulted in a change, which makes utility targets accessible from:
- the build-tree only, if the
LLVM_BUILD_UTILSflag is set (default
- both, build-tree and install-tree, if the
LLVM_INSTALL_UTILSflag is set too (default
LLVM_INSTALL_UTILS was set explicitly in the build that ends up in the llvm-9-dev apt package. Thus, the package does export
yaml-bench and other utility targets, even though it doesn’t provide them. This is a problem, because CMake checks that the referenced files do actually exist, when it runs the
As I was involved with the change that made this issue visible, I brought it up during the LLVM 9 release phase and explained the solution. Adding the dependency to llvm-9-tools was the workaround that was taken instead. Unfortunately, it didn’t respect the special case for
Update 2019-12-08: In 132a99b7
yaml-bench became part of the llvm-9-dev package.
I hope we can do better in the 10.0 release in Q2 2020. It’s up for discussion on the mailing list just now.