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.

The issue here is that LLVMExports.cmake references the yaml-bench exectuable, which is not part of the package or any of its dependencies.

Workaround

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.

Otherwise you can install libclang-common-9-dev, which happens to provide yaml-bench. Though, please note that it comes with 46MB of unrelated content.

Background

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:

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 find_package(LLVM) command.

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 yaml-bench.

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.