Somehow I am totally confused by how CMake works. Every time I think that I am getting closer to understanding how CMake is meant to be written, it vanishes in the next example I read. All I want to know is, how should I structure my project, so that my CMake requires the least amount of maintainance in the future. For example, I don't want to update my CMakeList.txt when I am adding a new folder in my src tree, that works exactly like all other src folders.
This is how I imagine my project's structure, but please this is only an example. If the recommended way differs, please tell me, and tell me how to do it.
myProject
src/
module1/
module1.h
module1.cpp
module2/
[...]
main.cpp
test/
test1.cpp
resources/
file.png
bin
[execute cmake ..]
By the way, it is important that my program knows where the resources are. I would like to know the recommended way of managing resources. I do not want to access my resources with "../resources/file.png"
After some research, I have now my own version of the most simple but complete CMake example. Here it is, and it tries to cover most of the basics, including resources and packaging.
One thing it does non-standard is resource handling. By default CMake wants to put them in /usr/share/, /usr/local/share/ and something equivalent on Windows. I wanted to have a simple zip/tar.gz file that you can extract anywhere and run. Therefore resources are loaded relative to the executable.
The basic rule to understand CMake commands is the following syntax:
<function-name>(<arg1> [<arg2> ...])
without comma or semicolon. Each argument is a string.foobar(3.0)
andfoobar("3.0")
is the same. You can set lists/variables withset(args arg1 arg2)
. With this variable setfoobar(${args})
andfoobar(arg1 arg2)
are effectively the same. A nonexistent variable is equivalent to an empty list. A list is internally just a string with semicolons to separate the elements. Therefore a list with just one element is by definition just that element, no boxing takes place.Variables are global. Built-in functions offer some form of named arguments by the fact that they expect some ids, like
PUBLIC
orDESTINATION
, in their argument list, to group the arguments. But that's not a language feature; those ids are also just strings, and parsed by the function implementation.You can clone everything from GitHub.
Note: While the above usage of
file(GLOB)
is appropriate here, where the question specifically asks for a technique to minimize the frequency of edits to CMakeLists.txt files with the addition of new source files, this technique is discouraged in the official documentation, and in the answers to these dedicated questions: #1, #2.