13

I am trying to understand the purpose behind CMake. Why it is designed like it is right now. Here are some questions I would like to have answered.

  • Why does CMake generate makefiles instead of just building the project?
  • Why are CMake files a series of commands and not just configuration files, e.g., .ini, .xml, and .yaml?
  • What are the commands that I write into the CMakeLists.txt file supposed to do? Just calling the compiler would be too easy I guess
  • In which order am I supposed to do the commands?
  • Is everything case insensitive? Can I write everything lowercase?
  • Why do tutorials advise me to list every source file explicitly?
  • How do I structure my CMakeLists.txt file to keep it short and simple to maintain? Every file I looked up in real projects looked very cluttered.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arne
  • 7,921
  • 9
  • 48
  • 66

3 Answers3

18

It can be difficult to understand how CMake works. I'll do my best to briefly answer some of the questions you posted.

Why does CMake generate makefiles instead of just building the project?

CMake is a cross-platform make system and is compiler independent. It doesn't generate just make build systems, but it also generates Visual Studio solution files. With the same CMakeList.txt file someone can easily create a Windows build (Visual Studio) or a Linux build (g++).

Why are CMake files a series of commands and not just configuration files, e.g., .ini, .xml, and .yaml?

Compilers don't use a universal configuration, so CMake must adapt for the target compiler.

CMake files are a series of commands to generate the appropriate configuration for the target compiler.

What are the commands that I write into the CMakeLists.txt file supposed to do? Just calling the compiler would be too easy I guess

They are supposed to generate the appropriate configuration for the target compiler, and they will if written correctly.

In which order am I supposed to do the commands?

In the order that matters, if the order matters at all. Yes, it's a vague answer, but it depends on the project. For example, the include() command will be used to add additional CMake files, and if you include them in the wrong order, it can break generation of the build system.

The first command in your CMake file must be the minimum required version with the latest version of CMake (3.0.1). From there it depends. :)

For example, this command will not work with versions of CMake less than 2.6. cmake_minimum_required (VERSION 2.6)

See some of the tutorial links at the end of this answer.

Is everything case insensitive? Can I write everything lowercase?

As stated on the CMake wiki's language syntax page, all of the commands are case insensitive, but you must consider case for contents passed to a command.

Why do tutorials advise me to list every source file explicitly?

Because you have to list every source file explicitly. This can be done inside a CMake file or a separate file list that is referenced in the CMake file. Please see Antonio's answer for a caveat of using a separate file list.

CMake does provide a command, aux_source_directory, which collects the names of all the source files in a specified directory and stores the list to a variable, but it should only be used for "generated" source files for the same reason mentioned in Antonio's answer.

How do I structure my CMakeLists.txt file to keep it short and simple to maintain? Every file I looked up in real projects looked very cluttered.

It's very easy to clutter a CMake file, and one way to help with this is to use .cmake files that you reference using the include command.

A good resource (although still under development) can be found on the CMake about page.

It's broken up into several sections:

  1. Overview
  2. Statistics (under development)
  3. Participants
  4. Documentation
  5. License
  6. Success Stories
  7. Publications
  8. News

Tutorials

CMake Tutorial - From the official CMake documentation page

Getting Started With CMake - A tutorial that uses CMake with GCC.

Using CMake To Build Qt Projects - A tutorial that uses CMake with Qt.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jmstoker
  • 3,315
  • 22
  • 36
  • thank you very much for your information. But this is still unclear: what is the appropriate configuration that my file needs to generate? I know it's "it depends on what you want". But I am always confused to help myself here. The documentation you linked here is a reference, what is exactly what I am not looking for, because it assumes that I already understood the general purpose. – Arne Sep 10 '14 at 21:55
  • @Arne, if you want a specific answer to a specific question, than I suggest you create a new question with those details. It's difficult to be specific without those details. – jmstoker Sep 10 '14 at 22:27
  • I thought my question was specific in asking for good in depth tutorial. The questions were just some examples, not all of my problems. It just feels wrong to start learning CMake by writing 20 Stack overflow questions. So I thought I would miss something that everybody knows except from me that I need to read. – Arne Sep 10 '14 at 22:56
  • 1
    @Arne your reasoning is sound, and so were your questions, but asking specifically for a tutorial is off-topic on SO. I reworded your question because I thought you asked good questions, and I didn't want it to be flagged for a close vote. I can relate to the frustration of learning CMake which motivated me to supply this answer. – jmstoker Sep 10 '14 at 23:28
  • Help me understand where you're lost. I added a 2nd tutorial link to my answer that shows a basic program and cmake file. What do you mean by "general purpose"? Did my answer not cover that? – jmstoker Sep 10 '14 at 23:31
  • at the moment I am trying to add a data directory with images and xml files to a project that need to be accessed from my program. The problem here is not that I don't find any answers, the problem is, that I can't understand why this question isn't super popular and has an at least 100 upvotes question somewhere. Doesn't any program have some resource files at some point? – Arne Sep 11 '14 at 00:19
  • @Arne The reason you probably don't find such a question about adding resources is that CMake doesn't provide a straight forward native method of doing it. Resources are added to projects using custom commands. I added a QT tutorial to my answer that shows how QT adds resources. – jmstoker Sep 11 '14 at 01:02
  • thanks for the link, but as I understand it, there are two major problems. It uses qt macros that I don't have, because I just use qt creator, it's not a qt project and I want absolutely nothing to be done with the file. A simple copy to my build. – Arne Sep 11 '14 at 01:18
  • isn't install supposed to do exactly what I want? But for some reason it doesn't do anything. – Arne Sep 11 '14 at 01:39
  • I don't have enough information to answer that. Can you create another question with the details? Then I can address it there. – jmstoker Sep 11 '14 at 02:55
  • thanks for your help, I found out that file(COPY ...) works best for me here. Wow that just took me 5 hours nonstop searching. I'm impressed by the intuitive design of CMake. – Arne Sep 11 '14 at 03:10
  • I always thought CMake was purely used to generate platform dependent Makefiles. Is that incorrect or do you mean that the compiler options are then written to that Makefile? – LandonZeKepitelOfGreytBritn Jul 15 '17 at 10:53
  • @trilolil CMake will generate the entire Makefile that once generated is platform dependent, but it doesn't always generate a Makefile. Such is the case for Visual Studio projects. – jmstoker Jul 17 '17 at 06:06
4

Since jmstoker already gave a very complete answer, I'll focus on this specific point:

Why do tutorials advise me to list every source file explicitly?

In practice, you can use globbing functions. However, the problem is that if you add a file, then you have to run CMake explicitly to make CMake aware of its presence. It's usually not a problem if you are working "alone", but in a shared project it can be a problem if somebody adds a file, you update, and then you compile, facing strange errors.

With Git there is a solution, that allows triggering "cmake ." every time a merge happens. Getting CMake to run before building after pulling from Git

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • The problem that I have with writing every file manually into my CMakeLists.txt, is that I have to do it manually. It would be nice if the list of files of my project would be generated by my ide (qtcreator), so that I do not need to touch anything manually when adding a file to the project. – Arne Sep 10 '14 at 22:00
  • That's a great point Antonio, well said! @Arne Yes, it would be easier to have the files added automatically through the IDE, but this feature doesn't exist natively in CMake. There are plugins for some IDEs that work with CMake that may provide this, but in the background they would be writing to a CMakeList.txt or .cmake file. – jmstoker Sep 10 '14 at 22:11
  • I don't like writing automatically into a file that should be hand written, because it becomes dirty very quickly. But that's another topic. Here I was just asking for introductory Tutorials. Not references and not success stories. Tutorials that make me understand to concepts of cmake to someone like me who thinks that every line of any build system is annoying and unnecessary, because it is already proven that generally it works also entirely without it like in go. Some tutorials that explain me why certain steps are necessary to build c++. That is important to me. – Arne Sep 10 '14 at 23:04
0

The end goal of CMake is to facilitate the act of providing some compiler of choice parameters needed for building a project (naturally written in some languages supported by CMake. CMake command project).

The input to CMake is some scripts, and guiding CMake how to generate input files to a native build system such as Microsoft Visual Studio or input to a build automation tool such as Make. CMake supports different native build systems and build automation tools and hence different types of generators for those (cmake-generators(7))

For better understanding, refer to this answer: What is a CMake generator?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
masih
  • 598
  • 1
  • 6
  • 10