为何执行两次cmake -S. -Bbuild命令才能成功构建基于LLVM的C++项目?
cmake fail to find LLVM on first run but succeed on the second? Let's break down what's happening here, starting with the key issues in your CMake configuration and execution flow:
1. You're using the wrong CMake variable for dependency lookup
In your CMakeLists.txt, you set:
SET(CMAKE_INSTALL_PREFIX "/home/abde_hn/llvm-project/build;/home/abde_hn/z3/build")
The CMAKE_INSTALL_PREFIX variable is meant to define where your built project will be installed, not where CMake should look for external dependencies like LLVM or Z3. The correct variable to guide find_package() searches is CMAKE_PREFIX_PATH.
On your first cmake -S. -Bbuild run, CMake only checks system default paths and paths specified in environment variables for LLVMConfig.cmake. Since your LLVM is built locally in /home/abde_hn/llvm-project/build (a non-standard path), find_package(LLVM) can't locate it and throws an error.
2. Why the second run works: CMake cache saves the day
Even though the first run errors out, CMake still creates basic cache files (like CMakeCache.txt) in the build directory. On the second run, CMake prioritizes these cached variables, and one of these scenarios is likely occurring:
- If you ever set the
LLVM_DIRenvironment variable or CMake cache variable for this project in the past, the cache retains that value, lettingfind_package()locate LLVM immediately on the second run. - Some CMake versions may indirectly include
CMAKE_INSTALL_PREFIXin the lookup path (this isn't standard behavior, but edge cases exist), so the second run picks up LLVM's config file from that directory. - Before the first run terminates with an error, CMake may have already processed enough logic to cache LLVM's path information (a rare but possible edge case).
3. Other fixes needed in your CMakeLists.txt
While we're at it, let's fix a few other issues that could cause unexpected behavior:
- Undefined variable in
project(): You use${This}inproject(${This}C CXX)before defining it. Moveset(This DEL)above theproject()command to fix this. - Syntax error in Z3 message:
$Z3_DIR}is missing an opening curly brace — it should be${Z3_DIR}. - Redundant
Z3_LIBRARIESset: Since you're usingfind_package(Z3 REQUIRED CONFIG), CMake automatically sets theZ3_LIBRARIESvariable. You don't need to manually specify the.sopath. - Incorrect
CXXFLAGSsyntax:set(CXXFLAGS +=llvm-config --cxxflags --ldflags --libs core)isn't valid CMake syntax. If you need to add these flags, use:
Though your existingset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $(llvm-config --cxxflags --ldflags --libs core)")llvm_map_components_to_libnamesusage is the more idiomatic CMake way to link LLVM components, so you can probably remove this line entirely.
Fixed key configuration snippet
Replace CMAKE_INSTALL_PREFIX with CMAKE_PREFIX_PATH and adjust the other issues:
cmake_minimum_required(VERSION 3.13.4) # Use CMAKE_PREFIX_PATH to tell CMake where to find dependencies SET(CMAKE_PREFIX_PATH "/home/abde_hn/llvm-project/build;/home/abde_hn/z3/build") set(This DEL) project(${This} C CXX) # Find LLVM find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") # Find Z3 find_package(Z3 REQUIRED CONFIG) message(STATUS "Found Z3 ${Z3_PACKAGE_VERSION}") message(STATUS "Using Z3Config.cmake in: ${Z3_DIR}") # Rest of your configuration...
With this change, cmake should find LLVM and Z3 on the first run without needing to re-execute the command.
内容的提问来源于stack exchange,提问作者Hany Erfan

