CMake - Adding dependencies to other projects
I'm quite new to CMake, and me and my colleagues decided on using it in some project we're developing. In this work, everybody is responsible for some module of the project. The layout is as follows:
ROOT -> Module1 ... -> Module2 (depends on Module 1) ... -> Module3 (depends on Module 2 and 1)
Each ModuleN has its own CMakeLists.txt file and must be able to be compiled, tested, and finished before they can be put together into the whole project. Now, I'm quite confused about what approach to use to make those dependencies work.
My research showed me some ways (like adding add_directory directives, etc.), but some of them complained that this way the projects can be compiled many times unnecessarily (like Module1 in this example); or requires a full path to be given.
The project won't be installed to the target machine, so I cannot use system library folders, includers, etc. either. Every developer has this repository in different folders, so I cannot give "exact" folders either. Can I use a syntax like "../Module1" for the add_directory command? Would this cause "unnecessary builds" as told?
Also, people usually recommend putting a CMakeLists.txt file in the root of the project as well, but I think this way we always have to build from the root directory - so modules cannot be built and tested separately.
What is the "noob way" to make this possible? As I said, I'm quite new to CMake, and honestly I don't even know the "keyword" to search for such a thing (searching "adding dependency" brings some results that I am simply drowned in :) )
Putting a CMakeLists.txt file at the root does the job. This doesn't mean you will always have to compile everything each time. When you will run the CMake command (or CMake GUI), you will generate a set of makefiles, an Xcode project, Visual C++ solution, etc. for the whole project. But you will be free to compile only what you want. The way you can achieve this will depend on the generation you will choose (IDE project, makefiles, Ninja files, etc.).
The main thing to understand is CMake generation and compilation are two separated steps.
- CMake generation: from CMakeLists.txt files, generate a project or a set of makefiles
- Compilation: from the "things" generated by CMake and your source code, create the libraries, software, etc.
The CMakeLists.txt in Module1 should create a library target [add_library(Module1 ...sources...)] (e.g. called Module1).
The target in Module2 can then link this library [target_link_library(mytarget Module1)].
Module 3 can then link the target in Module2.
You can also imbue the targets Module1 and Module2 with public and private include directories, so that targets that use them can inherit the include search paths.
Take a deep breath and read the documentation (twice!)