How to list all the targets in CMake's default (`all`) targets? - cmake

Is there a way to display all the targets that are included in CMake's default target?
I tried browsing all the CMakeLists.txt of my project by hand, but it is very tedious as there are many of them.

Related

How to build libraries with different options for different CMake targets?

I have a CMake project which consist from a set libraries.
This libraries links with a several programs.
Is it possible to replace compile options, for libraries which build for specifical programs?
For example, when cmake builds library for program A it defines first includes directory, for another program it includes directory B?

Using project() for dependent CMake subdirectories

I have several projects consisting of a few libraries, each living in its own subdirectory, knitted together by the topmost CMakeLists.txt file. I am in the habit of using project(<DIRNAME>) at the top of each CMakeLists.txt file and I try to structure the subprojects in such a way that they could be compiled separately from the top project. However, while this might make sense for standalone, core libraries, it cannot work for the libraries that depend on them because I need to do stuff like
target_link_libraries(gui core)
And core will nor be defined if I am trying to compile gui as a standalone project.
Is it wrong to use project() in this context, or am I missing something?
A Matter of Taste
This is in my opinion mainly a matter of taste. I don't think multiple project() commands itself are a problem, its more that projects I have seen using this approach tend to repeat itself in other parts and sometimes are running into problems with global cached variables.
Depending Libraries
The more relevant fact is, that the depending libraries will also add an include dependencies.
For standalone static library targets - not executable or shared library targets who really link the library - the simple target_link_libraries() command could be ignored with something like:
if (TARGET core)
target_link_libraries(gui core)
endif()
But the header files include dependency remains.
Standalone Projects in CMake
For me a (sub-)project to be really standalone needs not only the project() command, but it should also have a export(TARGETS ...) command. Then you could e.g. use find_package() commands to resolve any open dependencies with something like:
if (NOT TARGET core)
find_package(core REQUIRED)
endif()
target_link_libraries(gui core)
References
Making cmake library accessible by other cmake packages automatically
CMake share library with multiple executables

Which file organization for CMake? Should CMakeLists.txt include other files?

I use CMake to configure, build and install a C++ code.
I have defined some user options.
I have added an option to let CMake download external depedencies.
Etc, etc.
For the moment, everything concerning CMake is written in a single file CMakeLists.txt. There is also a configuration file 'config.cmake' which allows users to define various parameters such as verbosity level, paths to libraries, flags for compilers, etc.
What is a good file organization for CMake?
Should CMakeLists.txt file be divided into subfiles?
Thank you very much for your help!
A good file organization depends on how large your CMake logic is, or how large you expect it to become. Generally speaking:
Functionality that may get reused a lot you probably will want to organize into "per topic" .cmake files which contain macros, and include them in your other CMakeLists.txt files to load that functionality. You'll find lots of these already out there on the web (custom Find*.cmake files for locating particular system libraries are quite common, for example.) A common convention is to have a directory "CMake" in your toplevel source directory, although other configurations are possible.
If you have a lot of different build targets with their own unique source files (multiple libraries in a single project, for example) it is good practice to separate those into subdirectories and have one CMakeLists.txt file per subdirectory, with the toplevel CMakeLists.txt file using add_subdirectory to "hook them in" to the main build.
A "typical" structure for a project could look like this:
project/
CMakeLists.txt
README
CMake/
FindSpecialtyLib1.cmake
FindSpecialtyLib2.cmake
CustomCMakeMacroA.cmake
etc...
include/
CMakeLists.txt (for installing headers, etc. if needed.)
src/
CMakeLists.txt (top level switching logic per user settings, etc.)
lib1/
CMakeLists.txt
src1.cxx
src2.cxx
lib2/
CMakeLists.txt
src1.cxx
src2.c
private_header.h
That's just a hypothetical example, of course - you'll want to shape your logic to your specific project. Since you mention a config.cmake file, it's probably worth mentioning that the majority of variable setting of that sort is usually done in the cmake-gui or from -D definitions at the CMake command line, in my experience. A config.cmake works as a way to group options, but most users are probably going to start with the gui when it comes to setting things. I also recommend checking the CMake email archives for specific questions - I've found it to be an extremely helpful resource.

Build a library and multiple executables with one target name using cmake

I am currently working on migrating from an internal build system to cmake, and I am enjoying it so far.
Our source code is broken up into discrete named components. These components generally will build a library and a set of executables. I have setup cmake with a base CMakeLists.txt and then created a CMakeLists.txt in each code component that is then included in the base. The component CMakeLists.txt have multiple targets in them, one for a library and then a variable number of executables.
With our current system you can type something like:
make component_name
and that will build a library and any executables associated with component_name. Is something like that possible with cmake? Can I use one name to build all of the targets in a CMakeLists.txt file?
First define a custom target, then define the dependencies of the target:
ADD_CUSTOM_TARGET(component_name)
ADD_DEPENDENCIES(component_name lib1 lib2 exe1 exe2)

CMake: automatically find target dependencies in other CMake projects

If we have a case of highly decentralized development environment, where there are many repositories and projects, is there an existing functionality in CMake that automatically finds dependencies between targets without a top level CMake file?
The workflow is something like this, you specify a directory and all targets are default-configured in the given tree. Then you can go and build any of the projects. I am looking for a behavior similar to that when you build the Android OS.
There is no build-time dependency tracking in CMake across different projects. For this case you need to have a project on the top-level which adds all the subdirectories, so that the target names are available inside a single CMake project.
I am aware of one helper script around CMake which provides the required inter-project dependencies: https://github.com/aldebaran/qibuild
I would say that is getting close to a mature code base. However, it requires additional descriptor files for each project. Might be worth to have a look at it.