I opened CMakeLists.txt looking for the PHP equivalent of composer.json. A list of packages. A version constraint. Something I could run and then forget.
That is the wrong file.
CMake does not install my application. It does not even compile it. It describes targets - executables, libraries, the source files that belong to them - and then generates a build that some other tool actually runs. Ninja, Visual Studio, Make. I wrote a short TIL when that sentence first landed. This note is what I do with the file now that I know what it is for.
The mental model that finally stuck
In a Laravel app I know where to stand:
composer.json- what gets installedartisan- what I runpublic/index.php- where a request starts
In a CMake C++ project:
CMakeLists.txt- what exists as a target, and which files belong to it- the generator + compiler - what actually builds
main.cpp- where the process starts, when that file is even the right place to look (main.cpp is not index.php)
cmake . is not composer install. Configure can succeed and the build can still fail. That confused me longer than it should have.
What I look for first
I do not read the file top to bottom like a tutorial. I grep for the parts that answer web-developer questions:
project(- the name. Not important until it is.add_executable(/add_library(- the actual products. This is the “what are we building?”target_sources(- which.cpp/.qmlfiles are in the target. This is where I finally found the UI that Qt Designer would not open.find_package(- Qt, or whatever the project needs. This is closer to Composer than anything else in the file, and still not the same.target_link_libraries(- what gets linked. Dynamic vs static is a later problem.
If those five exist, I can usually find main or the QML entry without scrolling through a generated wall of include().
A shape, not my project file
I am not pasting a real application CMakeLists.txt here. Generated Qt files are noisy, and I am not going to republish a blob I do not want to maintain. The shape I keep in my head looks like this:
cmake_minimum_required(VERSION 3.16)
project(example LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Quick)
qt_add_executable(example
main.cpp
)
qt_add_qml_module(example
URI Example
QML_FILES
Main.qml
)
target_link_libraries(example PRIVATE Qt6::Quick)That is a sketch. Real files have more version pins, more Qt components, and more comments generated by a wizard. The sketch is enough to see: this is a map of targets, not a package lockfile.
What still feels strange
Coming from PHP:
- There is no request. The program lives until you quit it.
- Headers and
.cppfiles are a split I am still getting used to. CMake is the thing that has to know about both. - A missing file in
CMakeLists.txtdoes not 404. It fails at configure or at compile, with an error that assumes I already speak this dialect.
I still cannot write a non-trivial CMake module from memory. I need to read the file well enough to answer: what is the target, which sources does it include, and which main did I fail to find?
Next time the UI is QML and Designer looks empty, I will open CMakeLists.txt before I open another settings panel.