Underdisc / CMake

Information and samples on how to use CMake to build projects.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CMake

This repository contains information and samples on how to use CMake on a basic level to build projects.

Why CMake is Useful

CMake is essentially a wrapper around a typical Makefile. Though a Makefile is a good step to building a project quickly, CMake takes that to the next level by writing the Makefile for you, therefore automating the build process even more.

How to use this tutorial

In this repository, there should be multiple directories named 1, 2, and so on. Each directory covers a different part of CMake and how to use it effectively. In this tutorial, I will go through the important information each of these directories contains so you can quickly get started with CMake.

A Quick Disclaimer: While writing this tutorial I am learning CMake myself, but I figure that writing a tutorial while I learn the information will help me better understand how CMake is used and how it works. On top of that, if anyone is looking to learn how to use CMake, I can point them to this repository. With that said, if anyone has any corrections for me to make, please point them out to me so I can make those changes for myself and others.

Part 1 - Basic

To begin look in 1/. As with learning how to create a Makefile for the first time, I figure it is best to start by learning how to use CMake with one file. In 1/, you will find two files and one directory.

  • program.c
  • CMakeLists.txt
  • build

If the build directory is not there, just create it with mkdir build. program.c is just the source for this program and only contains a printf statement. CMakeLists.txt however contains the directions for CMake to use in order to create a Makefile for the project. If you open up CMakeLists.txt, you will find one line.

add_executable(program_name program.c)

This command adds a new executable target to your Makefile to be built. The first argument to this command is the name of the executable target. In this case, the target's name is program_name. The second argument is the file needed to build that target; program.c. This is the only line you need to have in order to build a Makefile for this simple program using CMake. This leads to a few questions, the most important of which is; Which compiler will be used since we did not provide the information? CMake will automatically figure out which compiler to use based off of the file extentions in your project. This can also be changed, but I will cover that later in this tutorial.

Now, the next step is to generate a Makefile with CMake and build the project. To do this, go to the empty directory 1/build/. This directory is here to separate everything needed for building the project from your source code. From here run the following.

cmake ..

Here, we are running cmake on the parent director. Within the parent directory is where our CMakeLists.txt file is located. CMake used that file in order to create the Makefile that you should now see within your build directory. Now you can do the following.

make
./program_name

The program should have built successfully and ran. You might also notice that CMake adds some very pretty output to the build process as well.

Part 2 - Multiple Files and Flags

Now, go out of 1/ and move to 2/ for the next step. Unlike the directory used for part 1, here you should find 3 files and 1 directory.

  • program.c
  • more_program.c
  • CMakeLists.txt
  • build

Like last time, if you do not see a build directory, just use mkdir build to create it. Now open up CMakeLists.txt in this directory. In this CMakeLists.txt file, you should see an edit and a few additions from the CMakeLists.txt displayed in part one. The first thing to break down in this file is the very last line (7).

add_executable(program_name program.c more_program.c)

This is almost exactly the same as the add_executable() command in the previous CMakeLists.txt file, however it contains the name of the new file used in this project; more_program.c. This does exactly as you might think. The new file will be added to the Makefile generated by CMake, therefore allowing more_program.c to be compiled into an object file and linked with the object file created from program.c for the final executable.

The more interesting part of this CMakeLists.txt file is what is located above the add_executable() command. On lines 3-5 you will find the following.

3. add_definitions(${MY_C_FLAGS})
4. set(MY_C_FLAGS "-O -Wall -Wextra -Werror -ansi -pedantic")
5. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_C_FLAGS}")

Like a regular language, CMake uses variables to keep track of certain information. This is what the following are; MY_C_FLAGS, CMAKE_C_FLAGS. They are just variables/definitions. Some variables are built into CMake, such as CMAKE_C_FLAGS, but you can create your own with the add_definitions command, which is what I did in the section of the CMake file pasted above.

After creating the definition, the next step is to set what that definition represents. This is done using the set(<1> "<2>") command. <1> is where the name of the definition should be. <2> is what that definition should be set to. In this particular example, I set the definition I created, MY_C_FLAGS, to the flags I wanted to use for compiling my program. CMake, however, will not use the that variable when compiling the program, it will use its own variable named CMAKE_C_FLAGS.

On line 5 is where the CMAKE_C_FLAGS variable gets set. Instead of setting it directly to the compiler flags we desire, though, we append the MY_C_FLAGS definition onto the current CMAKE_C_FLAGS. This is just a cleaner way of doing this in case the definition of CMAKE_C_FLAGS is already set. Just to be clear, setting CMAKE_C_FLAGS like MY_C_FLAGS was set on line 4 is an option, it's just not as clean.

Now, go into the build directory, run cmake and make just like it was ran in part one.

cmake ..
make

CMake should generate a Makefile, but once you run make, you should get an unused variable error from the compiler being used. Without the -Wall flag added in the CMake file, this error would not have popped up, therefore proving that the flag was successfully added to the compile command.

The next and last thing to cover here is the very first line of the CMakeLists.txt, which is actually fairly self-explanatory.

cmake_minimum_required(VERSION 3.5)

Here, we are simply telling CMake that if the current version on this machine is below 3.5, it will halt its processing of the project and spit out an error message.

References

CMake

CMake Commands

CMake Useful Variables

CMake Howto

Adding Flags With CMake

About

Information and samples on how to use CMake to build projects.


Languages

Language:C 57.5%Language:CMake 42.5%