Is there a way to hide some installs output from CMAKE? - cmake

I'm installing huge directories with CMAKE using
install(FILES ....)
I'm wondering if there was any way to hide/skip specific lines, because they're usually Up-to-date and i'm having large outputs of this hiding relevant informations.
Up-to-date: ....
If not, i'll find some workarounds with Batch scripts but i'd really like it to be in the CMakeLists.txt
Thank you.

There is CMAKE_INSTALL_MESSAGE variable for that.
Adding set(CMAKE_INSTALL_MESSAGE LAZY) to your CMakeLists.txt would skip the "Up-to-date" messages.
See docs for further information.

Related

How to use find_package in CMake? (Example: GMP library)

I'm trying to use find_package to include libraries in CMake.
This question talks about how to tell CMake to link to the GMP library (external). I am trying to follow the steps of the answer there but do not have any of the <name>Config.cmake or <name>-config.cmake files, as mentioned by some of the comments, which appears to be the default. The answer does not mention any solution for when you don't know how to get/find these files. The comments to that answer link to an old website (external) with a lot of broken links, that describes a list of Load Modules. It's unclear to me where these modules come from and how to get them.
According to the official CMake documentation (external), if the configuration files are not found, find_package falls back from "Module Mode" to "Config Mode". I don't understand what this means and in what cases this would be relevant, especially since the documentation discourages reading about "Config Mode".
The documentation says that
The file is first searched in the CMAKE_MODULE_PATH, then among the Find Modules provided by the CMake installation.
I am still confused about whether these configuration files are supposed to come with CMake or with the library in question and where they are supposed to be located. Probably both are possible but how does one know in a specific case?
Example code, trying to follow modern best practices:
# CMakeLists.txt (not working)
cmake_minimum_required(VERSION 3.2) # I have no idea what version I actually need
project (GMP_demo_project)
# Enable C++17 standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(GMP REQUIRED)
# Create the executable from sources
add_executable(GMP_demo GMP_demo.cpp)
target_link_libraries(GMP_demo gmp gmpxx)
The code outputs an error message along the lines of
CMake Error at CMakeLists.txt:10 (find_package):
By not providing "FindGMP.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "GMP", but
CMake did not find one.
Could not find a package configuration file provided by "GMP" with any of
the following names:
GMPConfig.cmake
gmp-config.cmake
Add the installation prefix of "GMP" to CMAKE_PREFIX_PATH or set "GMP_DIR"
to a directory containing one of the above files. If "GMP" provides a
separate development package or SDK, be sure it has been installed.
Question: How does one, in general, obtain and organize these configuration files (CMake Load Modules)? How can one expect another user to have these files on his system? My question is intended to be general and only use GMP as an example (although I am in fact interested in being able to use it).
Just as an aside, I can compile, link and execute my demo code just fine using gcc GMP_demo.cpp -lstdc++ -lgmp after having installed GMP as suggested by the library documentation. The problem is just getting CMake to do it. I can also just give CMake the absolute path of the library, which would of course be much easier but not portable (assuming one can get find_package to actually work and be portable with reasonable amounts of work).
How does one, in general, obtain and organize these configuration files (CMake Load Modules)?
Broadly speaking, there are three buckets these fall into:
Files provided directly by the package. This is the ideal solution, and would be what CMake calls Config mode. There would be a file called GMPConfig.cmake which cmake could find by searching preconfigured paths, or by providing a specific path at configuration time (cmake -DGMP_Dir=/path/to/GMP/install/root). The advantages of this approach are that generation of GMPConfig.cmake is mostly automatic, and the libraries can include things like installation paths and compilation flags. The disadvantage is that the library develops have to actually go to the effort of leveraging modern CMake, and not everybody does this.
Files provided directly by CMake. For common packages (e.g., boost) CMake ships FindXXX.cmake files that search well-known paths and take care of this for you. These work identically to the above from an end-user perspective, but which Find modules are available depends on the version of CMake you have installed.
Files provided by some random person that are copy/pasted into projects. How these works depends on the person who wrote it, so you'll have to read their documentation. Use your favorite search engine and try to find FindGMP.cmake, then drop it in a module folder somewhere and update CMAKE_MODULE_PATH appropriately.
How can one expect another user to have these files on his system?
It's your job to install whatever dependencies a package requires. Anything using modern CMake (bullet 1 listed above) should install the XXXConfig.cmake file as part of its installation. If a library is built by something other than CMake, you'd have to either hope for bullet #2, or find/write your own FindXXX.cmake file (bullet #3).
For your specific case, you might be better off with find_library, since your sample compilation line looks like it just needs to link.

Find out where CMake searches (and why)

Suppose I write this in a CMake file:
find_path(ISL_INCLUDE_DIR NAMES isl)
How do I find out where CMake searches to find a library named isl, and WHY it it searching these paths?
Non-solutions:
strace -e file -f cmake. This certainly tells me where CMake is probing (along with a lot of irrelevant extra information), but it doesn't tell me why CMake has decided to look in a particular directory.
Read the find_path documentation. This is a bit better: combined with ccmake, I can form hypotheses about what is being probed and then check and see if the variables line up. But this is not enough, for a few reasons: (1) I've noticed that CMake will search in the include/library directories associated with the CMake installation itself (so, for example, if I used conda to install CMake, the conda-distributed CMake will automatically pick up conda includes/libraries). I don't see anything in the documentation which indicates this ought to happen. (2) CMake will only give information about persistent variables, and not transient ones like CMAKE_PREFIX_PATH which are quite important to resolution.
Use --debug-output or --trace. These seem to give too much information and I don't know what to look for.
What I want is a way to make CMake tell me each directory it is looking in when it executes a find_path, why it is considering that directory, and which one it eventually decides fits. Is this at all possible?

How to make package built with make install available for cmake?

So, I'm trying to build an application that requires gtkglextmm on CentOS. So far, I grabbed the source (from here) for gtkglext and gtkglextmm, and (finally) figured out how to compile them and install them using ./configure then make then sudo make install. That was pretty cool to get that to work.
Now, I'm trying to build Degate with cmake and it's complaining that it can't find gtkglextmm. What do I need to do to get the gtkglextmm library I built, available for cmake?
Rephrase: Built and installed library a with make,make install. Now want to build application b that depends on a with cmake. How?
Thanks!
This is a newcomer's notes made for my team as we adopt cmake. It summarizes briefly what I thought would be somewhere in a novice's example. Although with references and suitable for novices, I am very new to the material and this example may suffer accordingly.
General info for this question is at: https://cmake.org/Wiki/CMake:How_To_Find_Libraries - in particular, find_package can be used on any of the named packages listed by the help command:
cmake --help-module-list
Note: the 'Find' is omitted (e.g., FindLibXml2 -> find_package(LibXml2) )
However, for this type of library, it is more likely that it will not be in that list, in which case you want to use find_library and find_path instead. A simple example is:
find_library(SQLITE3_LIB sqlite3) # simple because I did not need to give paths
find_path(SQLITE3_PATH sqlite3.h)
target_link_libraries( your_target_name ${SQLITE3_LIB} )
include_directories( ${SQLITE3_PATH} )
You do not need to test if these have the '-NOTFOUND' return value because cmake will exit with an error if they do:
...
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
SQLITE3_LIB
linked by target "test" in directory /home/matlab/QFDC_ROOT/api
-- Configuring incomplete, errors occurred!
Note that the all-capitalized 'SQLITE3_LIB' and 'SQLITE3_PATH' are the variable names that I chose. You choose the variable names. If you have other libraries and include directories, you can list them before and after this one and separated by spaces (I ordered them by their link order consistently for both, although I think include paths are insensitive).
Your case may not be so simple, in which case you want to use the CMake features described at find_library for providing CMake more information about where it should find that library. There are other Q&A on specifically that topic - my favorite is to produce your own FindXXX.cmake (although it is a very terse answer pointing you to an example).
In many cases, it is helpful to run make VERBOSE=1 to help you troubleshoot the process, such as cd build && cmake .. && make VERBOSE=1.
For even better diagnostics, I used DLRdave's answer to print out the INCLUDE_DIRS and I used a simple message to return the results of my variables:
message( STATUS "SQLITE3_LIB: ${SQLITE3_LIB} SQLITE3_PATH: ${SQLITE3_PATH}")
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
EDIT NOTE: this answer was effectively re-written 2016-04-08 after discovering that the previous day's implementation erred and confused find_library() and find_path().

When should I rerun cmake?

After running the cmake command once to generate a build system, when, if ever, should I rerun the cmake command?
The generated build systems can detect changes in the associated CMakeLists.txt files and behave accordingly. You can see the logic for doing so in generated Makefiles. The exact rules for when this will happen successfully are mysterious to me.
When should I rerun cmake? Does the answer depend on the generator used?
This blog post (under heading: "Invoking CMake multiple times") points out the confusion over this issue and states that the answer is actually 'never', regardless of generator, but I find that surprising. Is it true?
The answer is simple:
The cmake binary of course needs to re-run each time you make changes to any build setting, but you wont need to do it by design; hence "never" is correct regarding commands you have to issue.
The build targets created by cmake automatically include checks for each file subsequently [=starting from the main CMakeLists.txt file] involved or included generating the current set of Makefiles/VS projects/whatever. When invoking make (assuming unix here) this automatically triggers a previous execution of cmake if necessary; so your generated projects include logic to invoke cmake itself! As all command-line parameters initially passed (e.g. cmake -DCMAKE_BUILD_TYPE=RELEASE .. will be stored in the CMakeCache.txt, you dont need to re-specify any of those on subsequent invocations, which is why the projects also can just run cmake and know it still does what you intended.
Some more detail:
CMake generates book-keeping files containing all files that were involved in Makefile/Project generation, see e.g. these sample contents of my <binary-dir>/CMakeFiles/Makefile.cmake file using MSYS makefiles:
# The top level Makefile was generated from the following files:
set(CMAKE_MAKEFILE_DEPENDS
"CMakeCache.txt"
"C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/CMakeCCompiler.cmake.in"
"C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/RepositoryInfo.txt.in"
"<my external project bin dir>/release/ep_tmp/IRON-cfgcmd.txt.in"
"../CMakeFindModuleWrappers/FindBLAS.cmake"
"../CMakeFindModuleWrappers/FindLAPACK.cmake"
"../CMakeLists.txt"
"../CMakeScripts/CreateLocalConfig.cmake"
"../Config/Variables.cmake"
"../Dependencies.cmake"
"CMakeFiles/3.1.0/CMakeCCompiler.cmake"
"CMakeFiles/3.1.0/CMakeRCCompiler.cmake")
Any modification to any of these files will trigger another cmake run whenever you choose to start a build of a target. I honestly dont know how fine-grained those dependencies tracking goes in CMake, i.e. if a target will just be build if any changes somewhere else wont affect the target's compilation. I wouldn't expect it as this can get messy quite quickly, and repeated CMake runs (correctly using the Cache capabilities) are very fast anyways.
The only case where you need to re-run cmake is when you change the compiler after you started a project(MyProject); but even this case is handled by newer CMake versions automatically now (with some yelling :-)).
additional comment responding to comments:
There are cases where you will need to manually re-run cmake, and that is whenever you write your configure scripts so badly that cmake cannot possibly detect files/dependencies you're creating. A typical scenario would be that your first cmake run creates files using e.g. execute_process and you would then include them using file(GLOB ..). This is BAD style and the CMake Docs for file explicitly say
Note: We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
Btw this comment also sheds light on the above explained self-invocation by the generated build system :-)
The "proper" way to treat this kind of situations where you create source files during configure time is to use add_custom_command(OUTPUT ...), so that CMake is "aware" of a file being generated and tracks changes correctly. If for some reason you can't/won't use add_custom_command, you can still let CMake know of your file generation using the source file property GENERATED. Any source file with this flag set can be hard-coded into target source files and CMake wont complain about missing files at configure time (and expects this file to be generated some time during the (first!) cmake run.
Looking into this topic for reading the version information from a debian/changelog file (generation phase), I ran in the topic that cmake execution should be triggered as debian/changelog is modified. So I had the need to add debian/changelog to CMAKE_MAKEFILE_DEPENDS.
In my case, debian/changelog is read through execute_process. Execute_process unfortunately gives no possibility to add files processed to CMAKE_MAKEFILE_DEPENDS. But I found that running configure_file will do it. Actually I am really missing something like DEPENDENCIES in execute_process.
However, as I had the need to configure the debian/changelog file for my needs, the solution came implicitly to me.
I actually also found a hint about this in the official documentation of configure_file:
"If the input file is modified the build system will re-run CMake to re-configure the file and generate the build system again."
So using configure_file should be a safe to trigger the re-run of cmake.
From a user perspective, I would expect other commands to extend CMAKE_MAKEFILE_DEPENDS, too. E.g. execute_process (on demand) but also file(READ) (implicitly like configure_file). Perhaps there are others. Each read file is likely to influence the generation phase. As an alternative it would be nice to have a command to just extend the dependency list (hint for the cmake developers, perhaps one comes along).

How exactly does CMake work?

I'm not asking this for just myself. I hope this question will be a reference for the many newbies who like me, found it utterly perplexing about what exactly what was going on behind the scenes when for such a small CMakeLists.txt file
cmake_minimum_required (VERSION 2.6)
project(Tutorial)
add_executable(Tutorial tutorial.cpp)
and such a small tutorial.cpp
int main() { return 0; }
there are so many files generated
CMakeCache.txt cmake_install.cmake Makefile
CMakeLists.txt tutorial.cpp
and a CMakeFiles folder with so many files and folders
CMakeCCompiler.cmake CMakeOutput.log Makefile.cmake
cmake.check_cache CMakeSystem.cmake progress.marks
CMakeCXXCompiler.cmake CMakeTmp TargetDirectories.txt
CMakeDetermineCompilerABI_C.bin CompilerIdC Tutorial.dir
CMakeDetermineCompilerABI_CXX.bin CompilerIdCXX
CMakeDirectoryInformation.cmake Makefile2
Not understanding what was going on behind the scenes (i.e: why so may files had to be generated and what their purpose was), was the biggest obstacle in being able to learn CMake.
If anyone knows, could you please explain it for the sake of posterity? What is the purpose of these files, and when I type cmake ., what exactly is cmake configuring and generating before it builds the project?
The secret is that you don't have to understand what the generated files do.
CMake introduces a lot of complexity into the build system, most of which only pays off if you use it for building complex software projects.
The good news is that CMake does a good job of keeping a lot of this messiness away from you: Use out-of-source builds and you don't even have to look at the generated files. If you didn't do this so far (which I guess is the case, since you wrote cmake .), please check them out before proceeding. Mixing the build and source directory is really painful with CMake and is not how the system is supposed to be used.
In a nutshell: Instead of
cd <source_dir>
cmake .
always use
cd <build_dir_different_from_source_dir>
cmake <source_dir>
I usually use an empty subfolder build inside my source directory as build directory.
To ease your pain, let me give a quick overview of the relevant files which CMake generates:
Project files/Makefiles - What you are actually interested in: The files required to build your project under the selected generator. This can be anything from a Unix Makefile to a Visual Studio solution.
CMakeCache.txt - This is a persistent key/value string storage which is used to cache value between runs. Values stored in here can be paths to library dependencies or whether an optional component is to be built at all. The list of variables is mostly identical to the one you see when running ccmake or cmake-gui. This can be useful to look at from time to time, but I would recommend to use the aforementioned tools for changing any of the values if possible.
Generated files - This can be anything from autogenerated source files to export macros that help you re-integrate your built project with other CMake projects. Most of these are only generated on demand and will not appear in a simple project such as the one from your question.
Anything else is pretty much noise to keep the build system happy. In particular, I never needed to care about anything that is going on inside the CMakeFiles subdirectory.
In general you should not mess with any of the files that CMake generates for you. All problems can be solved from within CMakeLists.txt in one way or the other. As long as the result builds your project as expected, you are probably fine. Do not worry too much about the gory details - as this is what CMake was trying to spare you of in the first place.
As stated on its website:
Cmake is cross-platform, open-source build system for managing the build process of software using a compiler-independent method
In most cases it is used to generate project/make files - in your example it has produced Makefile which are used to build your software (mostly on Linux/Unix platform).
Cmake allows to provide cross platform build files that would generate platform specific project/make files for particular compilation/platform.
For instance you may to try to compile your software on Windows with Visual Studio then with proper syntax in your CMakeLists.txt file you can launch
cmake .
inside your project's directory on Windows platform,Cmake will generate all the necessary project/solution files (.sln etc.).
If you would like to build your software on Linux/Unix platform you would simply go to source directory where you have your CMakeLists.txt file and trigger the same cmake . and it will generate all files necessary for you to build software via simple make or make all.
Here you have some very good presentation about key Cmake functionalities http://www.elpauer.org/stuff/learning_cmake.pdf
EDIT
If you'd like to make platform dependent library includes / variable definitions etc. you can use this syntax in CMakeLists.txt file
IF(WIN32)
...do something...
ELSE(WIN32)
...do something else...
ENDIF(WIN32)
There is also a lot of commands with use of which you are able to prevent the build from failing and in place Cmake will notify you that for instance you do not have boost libraries filesystem and regex installed on your system. To do that you can use the following syntax:
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
Having checked that it will generate the makefiles for appropriate system/IDE/compiler.
Exactly how CMake works is a question for the developers, so this question can't be answered here.
However we can give a touch of useful guidance as far as when you should use CMake and when you therefore need to worry about how it works. I'm not a fan of "oh it just works" answers either - because, especially in software, NOTHING ever "just works" and you ALWAYS have to get into the nitty-gritty details at some point.
CMake is an industrial-strength tool. It automates several VERY complex process and takes into account many variables of which you may not be aware, especially as a fairly new developer, probably working with limited knowledge of all the operating systems and build tools CMake can handle. The reason so many files are generated and why things seem so complex is because all of those other systems are complex and must be accounted for and automated. Additionally there are the issues of "caching" and other time-saving features of the tool To understand everything in CMake would mean understanding everything in these build tools and OS's and all the possible combinations of these variables, which as you can imagine is impossible.
It's important to note that if you're not in charge of managing a large cross-platform build system, and your code base is a few KLOC, maybe up to 100KLOG, using CMake seems a little bit like using a 100,000 dollar forestry tree removal machine to remove weeds from your 2 foot by 2 foot flower garden. (By the way, if you've never seen such a machine, you should look for one on youtube, they're amazing)
If your build system is small and simple it's likely to be better to just write your own makefiles by hand or script them yourself. When your makefiles become unwieldy or you need to build a version of your system on another platform, then you can switch over to CMake. At that point, you'll have lots of problems to solve and you can ask more focused questions about it. In the meantime, check out some of the great books that have been written about CMake, or even better, write one yourself! 8)