cmake

I haven't been doing much with writing/compiling c programs of late. So I didn't really notice the move from using make to using cmake for the build environment. We've been having some issues at work with this, so I've spent a few days trying to learn it. I'm not at expert at this at all, but I have picked up a few things. So I want to document them here.

Here's a simple hello.c program.

#include <stdio.h>

int main() {
printf("Hello world!\n");
return 0;
}

It can be compiled with:

yo:hello $ gcc hello.c -o hello
yo:hello $ ./hello
Hello world!

How would I do this using cmake?

yo:hello $ mkdir build
yo:hello $ touch CMakeLists.txt
yo:hello $ ll
total 32
-rw-r--r--  1 maryh  staff     0 Apr 24 10:23 CMakeLists.txt
drwxr-xr-x  2 maryh  staff    68 Apr 24 10:23 build
-rwxr-xr-x  1 maryh  staff  8432 Apr 24 10:09 hello
-rw-r--r--  1 maryh  staff    73 Apr 24 10:06 hello.c

The file that cmake looks for is called CMakeLists.txt. Edit this file so it looks like this:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(hello)
add_executable(hello hello.c)

All this does is check that we're using at least version 3 of cmake. Not necessary for this, but for some other work programs, I needed that. The project line sets up the project and stores the name in the variable PROJECT_NAME. And if it's the top-level CMakeLists.txt file, it also stores it in CMAKE_PROJECT_NAME. And the add_executable line adds an executable target (for us called hello) that's built from the source file(s) (for us we only have hello.c).

That's all that is needed. It's nice to make the build directory and run the cmake program there because it makes things much easier to delete all the files if you're doing various iterations on things.

To compile then, go to the build directory and run:

yo:hello $ cd build
yo:build $ cmake ../
-- The C compiler identification is AppleClang 9.1.0.9020039
-- The CXX compiler identification is AppleClang 9.1.0.9020039
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/maryh/Documents/C/hello/build

Now use make to compile the program.

yo:build $ make
Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/hello.c.o
[100%] Linking C executable hello
[100%] Built target hello
yo:build $ ll
total 80
-rw-r--r--   1 maryh  staff  13521 Apr 24 10:33 CMakeCache.txt
drwxr-xr-x  15 maryh  staff    510 Apr 24 10:34 CMakeFiles
-rw-r--r--   1 maryh  staff   4751 Apr 24 10:33 Makefile
-rw-r--r--   1 maryh  staff   1373 Apr 24 10:33 cmake_install.cmake
-rwxr-xr-x   1 maryh  staff   8432 Apr 24 10:34 hello
yo:build $ ./hello
Hello world!

This is definitely overkill for such a simple program, but those are the basic steps for more elaborate programs. And the key file to edit is basically CMakeLists.txt.