Reputation: 93
I am wondering how is cmake finding my llvm cmake configuration if I haven't given it any variable telling it where to find it.
I am an LLVM newcomer. I am building a Hello World LLVM pass. I am on Ubuntu 16.04. My version of LLVM is 8.0.0. My version of CMake is 3.5.1.
This is my /CMakeLists.txt file:
cmake_minimum_required(VERSION 3.1)
project(FunctionDebugger)
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_subdirectory(FunctionDebugger)
set(CMAKE_VERBOSE_MAKEFILE on)
This is the FunctionDebugger/CMakeLists.txt file:
add_library(LLVMFunctionDebugger MODULE
FunctionDebugger.cpp
)
set_target_properties(LLVMFunctionDebugger PROPERTIES
COMPILE_FLAGS "-fno-rtti -std=c++11"
)
I configure and compile like this:
mkdir build && cd build
cmake ..
make
It correctly compiles and links a shared library called libLLVMFunctionDebugger.so. What I don't understand is how cmake could find the package requested in:
# <project-root>/CMakeLists.txt
find_package(LLVM REQUIRED CONFIG)
I am not giving it any path nor I have anything defined in the environment but the path to the LLVM binaries.
I read the CMake documentation, but it says that the find_package
looks in folders under CMAKE_PREFIX_PATH. I print that variable with message(STATUS ${CMAKE_PREFIX_PATH})
and the output is empty.
Upvotes: 5
Views: 4597
Reputation: 150
Since cmake 3.17, you can use cmake --debug-find <cmake-options>
to ask cmake to output a bunch of debugging information on find_* functions. On my machine, it outputs
Standard system environment variables [CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH].
/home/jiaqi/Documents/LLVM/llvm-project/build
/home/jiaqi/.local
/home/jiaqi/.yarn
/home/jiaqi/anaconda3
/home/jiaqi/anaconda3/condabin
/usr/local
/usr
/
/usr/games
/usr/local/games
/snap
... outputs omitted...
find_package considered the following locations for LLVM's Config module:
/home/jiaqi/Documents/LLVM/Test/build/CMakeFiles/pkgRedirects/LLVMConfig.cmake
/home/jiaqi/Documents/LLVM/Test/build/CMakeFiles/pkgRedirects/llvm-config.cmake
/home/jiaqi/Documents/LLVM/llvm-project/build/LLVMConfig.cmake
/home/jiaqi/Documents/LLVM/llvm-project/build/llvm-config.cmake
/home/jiaqi/Documents/LLVM/llvm-project/build/cmake/LLVMConfig.cmake
/home/jiaqi/Documents/LLVM/llvm-project/build/cmake/llvm-config.cmake
/home/jiaqi/Documents/LLVM/llvm-project/build/lib/cmake/llvm/LLVMConfig.cmake
The file was found at
/home/jiaqi/Documents/LLVM/llvm-project/build/lib/cmake/llvm/LLVMConfig.cmake
So, the cmake is using Config mode here and the file is located at /home/jiaqi/Documents/LLVM/llvm-project/build/lib/cmake/llvm/LLVMConfig.cmake
To figure out how cmake finds the LLVMConfig.cmake, take a look at https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
For step 5, it says the cmake will search the environment variable $PAT, and note that
Path entries ending in /bin or /sbin are automatically converted to their parent directories.
Since I have put the path to llvm executables in $PATH:
$ echo $PATH
/home/jiaqi/Documents/LLVM/llvm-project/build/bin:/home/jiaqi/.local/bin:/home/jiaqi/.yarn/bin:/home/jiaqi/anaconda3/bin:/home/jiaqi/anaconda3/condabin:/home/jiaqi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
The folder /home/jiaqi/Documents/LLVM/llvm-project/build will be used as prefix. According to https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure, the folder <prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/
will be searched.
Upvotes: 3
Reputation: 1811
Your set-up looks correct and clearly CMake
is finding LLVMConfig.cmake
script (i.e. the script that find_package
consumes to propagate the necessary CMake
variables with LLVM 8 set-up).
On the Ubuntu 16.04 machine that I have access to, LLVMConfig.cmake
is located in /usr/lib/llvm-8/lib/cmake/llvm/LLVMConfig.cmake
, but there's also a symlink in /usr/lib/llvm-8/cmake/
. So the natural questions is: does CMake
know that it should look there? The answer is yes. In CMake docs you can see that one of the search paths is:
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)
You can verify that usr
is on the list of prefixes by printing CMAKE_SYSTEM_PREFIX_PATH
. On my machine that's set-up to:
/usr/local;/usr;/;/usr;/usr/local
Finally, you can print LLVM_DIR
in your CMake
script to check which version/installation of LLVM
was picked by find_package
. The variable will be empty on the first execution of CMake
, but then find_package
finds LLVM-8, the variable is set and saved in CMakeCache.txt
.
Hope this helps.
EDIT
This answer was tested on Ubuntu 16.04 on which LLVM 8 was installed in the default, system-wide location through apt-get
. If you install LLVM 8 elsewhere, then there are various ways of pointing CMake
to the right location, see the docs for find_package. Editing the PATH
variable is one of them:
- Search the standard system environment variables. This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is passed. Path entries ending in /bin or /sbin are automatically converted to their parent directories:
PATH
Upvotes: 3