Let me describe what I think is a sufficiently common use case, that it should be supported. Consider a project which consists of a library and a set of executable that use that library. A straightforward approach is to add_library, followed by a sequence of add_executable() target_link_lib() pairs.
This is a lot of boilerplate coding. It would be nice to able to do something like set(PROJECT_LINK_LIBS, lib1 ...), and have cmake remove the extra boilerplate.
Thinking on this more, I realize I would like a link_libraries function that behaves similarly to include_directories. I would argue that this:
Would be useful in a lot of cases.
Would lead to dryer CMakeLists.
Would encourage better code organizations -- there would be a natural incentive to organize the folders, code, and executables in such a way that all executables have the same dependancies -- certainly a clean practice.
Is there anything like this?
As mentioned at https://stackoverflow.com/a/50295894/129550 the requested link_libraries(example example2) function is actually now a part of cmake.
This answer might be obsolete:
Check the new set of variables CMAKE_<LANG>_STANDARD_LIBRARIES
Original Answer:
It appears that now a CMAKE_STANDARD_LIBRARIES variable exists, where you can append the libraries according to your need. However, this variable seemingly expect full path to the libraries.
See here.
Related
I am working on a free-software project which involves high performance computing and the MPI library.
In my code, I need to know the size of the MPI_Offset type, which is defined in mpi.h.
Normally such projects would be build using autotools and this problem would be easily solved. But for my sins, I am working with a CMake build and I can't find any way to perform this simple task. But there must be a way to do - it is commonly done on autotools projects, so I assume it is also possible in CMake.
When I use:
check_type_size("MPI_Offset" SIZEOF_MPI_OFFSET)
It fails, because mpi.h is not included in the generated C code.
Is there a way to tell check_type_size() to include mpi.h?
This is done via CMAKE_EXTRA_INCLUDE_FILES:
INCLUDE (CheckTypeSize)
find_package(MPI)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
SET(CMAKE_EXTRA_INCLUDE_FILES "mpi.h")
check_type_size("MPI_Offset" SIZEOF_MPI_OFFSET)
SET(CMAKE_EXTRA_INCLUDE_FILES)
It may be more common to write platform checks with autotools, so here is some more information on how to write platform checks with CMake.
On a personal note, while CMake is certainly not the most pleasant exercise, for me autotools is reserved for the capital sins. It is really hard to me to defend CMake, but in this instance, it is even documented. Naturally, setting a separate "variable" that you even have to reset after the fact, instead of just passing it as a parameter, is clearly conforming to the surprising "design principles" of CMake.
Everything is in the title, but for more context informations:
I am creating a library, where all components are independent (it's only because it's easier to manage 1 git repo, really).
In that library's root folder, I have 1 sub-folder for each part of the library's components, with exactly 3 "interesting folders" (src,tests,include/components_name). I have hardcoded those folders in a foreach loop so that all actions will be done for all modules by default.
The problem seems to be that, one of the modules is named "option_parser" which is, indeed, relatively generic, and also seems to be "reserved" by cmake, and same for everything derived from it. I've tried "option_parser_test", "option_parser_tests", and other random names based on "option_parser_" root.
So, here is my question: where I can learn how to avoid names that cmake reserves?
And how can I affect them anyway to my binaries (because, I feel like it's stupid to change a project's name because of a build system. Might be a strong enough reason to switch it.)
It's really quite simple. Use these three commands to see all reserved words:
cmake --help-command-list
cmake --help-variable-list
cmake --help-property-list
The answer of Cinder Biscuits above should probably already help you.
Additionally, you should probably read CMake's own documentation regarding the CMake language and in particular the note in the "Variables" section:
Note: CMake reserves identifiers that:
begin with CMAKE_ (upper-, lower-, or mixed-case), or
begin with _CMAKE_ (upper-, lower-, or mixed-case), or
begin with _ followed by the name of any CMake Command.
I have to build a slightly patched version of GCC for a project and than compile the rest of the project with it. I am wondering what is the best way to do this. I am currently using ExternalProject_Add to build the compiler as a dependency for other binaries, but I don't know how to change the compiler for a part of the project.
Your best bet is probably to structure things as a superbuild. A top level project would have two subprojects built using ExternalProject_Add. The compiler would be the first subproject and the second would be your actual project which could then make use of the compiler by making your real subproject depend on the compiler subproject.
A second alternative is discussed here where your actual project remains as the top level project, but the compiler is built as a sub-build invoked via external_process(). I've used this approach for real world situations and while it does work, I'd personally still go with the superbuild approach if I had the choice since it's a bit cleaner and perhaps better understood by other developers.
Lastly, consider whether something like hunter might be able to take care of building your compiler for you. Depending on what/how you need to patch GCC, this may or may not be the most attractive approach.
I would use two CMake projects, one building your compiler, the other building your actual project with your built compiler. The CMake compiler is such an essential part of CMake, that changing is asking for trouble.
If you prefer having everything in one project, you can call your actual project with add_custom_command and call for a sub-folder. As a user this would be more surprising, but could lead to a better integration.
The CMake manual of Qt 5 uses find_package and says:
Imported targets are created for each Qt module. Imported target names should be preferred instead of using a variable like Qt5<Module>_LIBRARIES in CMake commands such as target_link_libraries.
Is it special for Qt or does find_package generate imported targets for all libraries? The documentation of find_package in CMake 3.0 says:
When the package is found package-specific information is provided through variables and Imported Targets documented by the package itself.
And the manual for cmake-packages says:
The result of using find_package is either a set of IMPORTED targets, or a set of variables corresponding to build-relevant information.
But I did not see another FindXXX.cmake-script where the documentation says that a imported target is created.
find_package is a two-headed beast these days:
CMake provides direct support for two forms of packages, Config-file Packages
and Find-module Packages
Source
Now, what does that actually mean?
Find-module packages are the ones you are probably most familiar with. They execute a script of CMake code (such as this one) that does a bunch of calls to functions like find_library and find_path to figure out where to locate a library.
The big advantage of this approach is that it is extremely generic. As long as there is something on the filesystem, we can find it. The big downside is that it often provides little more information than the physical location of that something. That is, the result of a find-module operation is typically just a bunch of filesystem paths. This means that modelling stuff like transitive dependencies or multiple build configurations is rather difficult.
This becomes especially painful if the thing you are trying to find has itself been built with CMake. In that case, you already have a bunch of stuff modeled in your build scripts, which you now need to painstakingly reconstruct for the find script, so that it becomes available to downstream projects.
This is where config-file packages shine. Unlike find-modules, the result of running the script is not just a bunch of paths, but it instead creates fully functional CMake targets. To the dependent project it looks like the dependencies have been built as part of that same project.
This allows to transport much more information in a very convenient way. The obvious downside is that config-file scripts are much more complex than find-scripts. Hence you do not want to write them yourself, but have CMake generate them for you. Or rather have the dependency provide a config-file as part of its deployment which you can then simply load with a find_package call. And that is exactly what Qt5 does.
This also means, if your own project is a library, consider generating a config file as part of the build process. It's not the most straightforward feature of CMake, but the results are pretty powerful.
Here is a quick comparison of how the two approaches typically look like in CMake code:
Find-module style
find_package(foo)
target_link_libraries(bar ${FOO_LIBRARIES})
target_include_directories(bar ${FOO_INCLUDE_DIR})
# [...] potentially lots of other stuff that has to be set manually
Config-file style
find_package(foo)
target_link_libraries(bar foo)
# magic!
tl;dr: Always prefer config-file packages if the dependency provides them. If not, use a find-script instead.
Actually there is no "magic" with results of find_package: this command just searches appropriate FindXXX.cmake script and executes it.
If Find script sets XXX_LIBRARY variable, then caller can use this variable.
If Find script creates imported targets, then caller can use these targets.
If Find script neither sets XXX_LIBRARY variable nor creates imported targets ... well, then usage of the script is somehow different.
Documentation for find_package describes usual usage of Find scripts. But in any case you need to consult documentation about concrete script (this documentation is normally contained in the script itself).
I am currently looking at replacements for the old make system for some projects. One of the alternatives I am currently looking at is cmake. However from what I know so far, CMake prefers to have one configuration file for each directory, similar to what Autotools and others prefer as well.
I know that recursive make should be considered harmfull, because not the whole dependency graph is know at all times (see the paper for details). For that reason other tools, which rely on recursive make, either do not work correctly in all cases or need some wrappers to work around these problems.
I am currently trying to figure out how CMake handles this case, and if the issues mentioned in the paper were taken into account in the design. I will try out the examples mentioned in the paper, but in case they work, it will not give me a certainty, that recursive builds work in all cases.
So the main question is: Was this issue taken into consideration for CMake or not? If so where can I read anything about their solution.
EDIT:
I found the CMake FAQ entry on this issue, but I am not really satisfied by the answer. I guess the real answer is in there somewhere, but I cannot find it, because I have no knowledge so far of CMake internals and I am not planning on learning them, if I might decide beforehand, that it is not the right tool for my purposes.
CMake does not generate one makefile per CMakeLists.txt. It collects all information from all of them and than creates something, that is unbelievably complex, but presumably written that way exactly so that it's reliable and ensures files are rebuilt if the relevant CMakeLists.txt changes.