2.1. Basic build with CMake

If we want to achieve same results (and even more) four the source code as listed in Final source code for basic compilation, we would not write the Makefile. But rather, we will write a CMakeLists.txt.

A very basic CMakeLists.txt for that purpose would look like this.

1
2
3
4
5
6
7
cmake_minimum_required (VERSION 2.8.11)

project (greeting)

add_executable (greeting_en main.c greeting_en.c)
add_executable (greeting_fr main.c greeting_fr.c)
add_executable (greeting_es main.c greeting_es.c)

To compile that file with GCC, the command would be.

mkdir _build
cd _build
cmake .. -G "Unix Makefiles"

When the above command completes successfully, the compilation output would be:

-- The C compiler identification is AppleClang 8.0.0.8000038
-- The CXX compiler identification is AppleClang 8.0.0.8000038
-- 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/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake/_build

The generated Makefile would look as below. (Note, the contents may change from platform to platform )

# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.7

# Default target executed when no arguments are given to make.
default_target: all

.PHONY : default_target

# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:


#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:


# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =

.SUFFIXES: .hpux_make_needs_suffix_list


# Suppress display of executed commands.
$(VERBOSE).SILENT:


# A target that is always out of date.
cmake_force:

.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /usr/local/Cellar/cmake/3.7.1/bin/cmake

# The command to remove a file.
RM = /usr/local/Cellar/cmake/3.7.1/bin/cmake -E remove -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /Users/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /Users/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake/_build

#=============================================================================
# Targets provided globally by CMake.

# Special rule for the target rebuild_cache
rebuild_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
	/usr/local/Cellar/cmake/3.7.1/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache

# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache

.PHONY : rebuild_cache/fast

# Special rule for the target edit_cache
edit_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
	/usr/local/Cellar/cmake/3.7.1/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache

# Special rule for the target edit_cache
edit_cache/fast: edit_cache

.PHONY : edit_cache/fast

# The main all target
all: cmake_check_build_system
	$(CMAKE_COMMAND) -E cmake_progress_start /Users/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake/_build/CMakeFiles /Users/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake/_build/CMakeFiles/progress.marks
	$(MAKE) -f CMakeFiles/Makefile2 all
	$(CMAKE_COMMAND) -E cmake_progress_start /Users/poo/data/p/test-ex-books/sw-build-system/book/code/0200_cmake/_build/CMakeFiles 0
.PHONY : all

# The main clean target
clean:
	$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean

# The main clean target
clean/fast: clean

.PHONY : clean/fast

# Prepare targets for installation.
preinstall: all
	$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall

# Prepare targets for installation.
preinstall/fast:
	$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast

# clear depends
depend:
	$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend

#=============================================================================
# Target rules for targets named greeting_fr

# Build rule for target.
greeting_fr: cmake_check_build_system
	$(MAKE) -f CMakeFiles/Makefile2 greeting_fr
.PHONY : greeting_fr

# fast build rule for target.
greeting_fr/fast:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/build
.PHONY : greeting_fr/fast

#=============================================================================
# Target rules for targets named greeting_es

# Build rule for target.
greeting_es: cmake_check_build_system
	$(MAKE) -f CMakeFiles/Makefile2 greeting_es
.PHONY : greeting_es

# fast build rule for target.
greeting_es/fast:
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/build
.PHONY : greeting_es/fast

#=============================================================================
# Target rules for targets named greeting_en

# Build rule for target.
greeting_en: cmake_check_build_system
	$(MAKE) -f CMakeFiles/Makefile2 greeting_en
.PHONY : greeting_en

# fast build rule for target.
greeting_en/fast:
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/build
.PHONY : greeting_en/fast

greeting_en.o: greeting_en.c.o

.PHONY : greeting_en.o

# target to build an object file
greeting_en.c.o:
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/greeting_en.c.o
.PHONY : greeting_en.c.o

greeting_en.i: greeting_en.c.i

.PHONY : greeting_en.i

# target to preprocess a source file
greeting_en.c.i:
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/greeting_en.c.i
.PHONY : greeting_en.c.i

greeting_en.s: greeting_en.c.s

.PHONY : greeting_en.s

# target to generate assembly for a file
greeting_en.c.s:
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/greeting_en.c.s
.PHONY : greeting_en.c.s

greeting_es.o: greeting_es.c.o

.PHONY : greeting_es.o

# target to build an object file
greeting_es.c.o:
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/greeting_es.c.o
.PHONY : greeting_es.c.o

greeting_es.i: greeting_es.c.i

.PHONY : greeting_es.i

# target to preprocess a source file
greeting_es.c.i:
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/greeting_es.c.i
.PHONY : greeting_es.c.i

greeting_es.s: greeting_es.c.s

.PHONY : greeting_es.s

# target to generate assembly for a file
greeting_es.c.s:
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/greeting_es.c.s
.PHONY : greeting_es.c.s

greeting_fr.o: greeting_fr.c.o

.PHONY : greeting_fr.o

# target to build an object file
greeting_fr.c.o:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/greeting_fr.c.o
.PHONY : greeting_fr.c.o

greeting_fr.i: greeting_fr.c.i

.PHONY : greeting_fr.i

# target to preprocess a source file
greeting_fr.c.i:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/greeting_fr.c.i
.PHONY : greeting_fr.c.i

greeting_fr.s: greeting_fr.c.s

.PHONY : greeting_fr.s

# target to generate assembly for a file
greeting_fr.c.s:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/greeting_fr.c.s
.PHONY : greeting_fr.c.s

main.o: main.c.o

.PHONY : main.o

# target to build an object file
main.c.o:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/main.c.o
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/main.c.o
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/main.c.o
.PHONY : main.c.o

main.i: main.c.i

.PHONY : main.i

# target to preprocess a source file
main.c.i:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/main.c.i
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/main.c.i
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/main.c.i
.PHONY : main.c.i

main.s: main.c.s

.PHONY : main.s

# target to generate assembly for a file
main.c.s:
	$(MAKE) -f CMakeFiles/greeting_fr.dir/build.make CMakeFiles/greeting_fr.dir/main.c.s
	$(MAKE) -f CMakeFiles/greeting_es.dir/build.make CMakeFiles/greeting_es.dir/main.c.s
	$(MAKE) -f CMakeFiles/greeting_en.dir/build.make CMakeFiles/greeting_en.dir/main.c.s
.PHONY : main.c.s

# Help Target
help:
	@echo "The following are some of the valid targets for this Makefile:"
	@echo "... all (the default if no target is provided)"
	@echo "... clean"
	@echo "... depend"
	@echo "... greeting_fr"
	@echo "... rebuild_cache"
	@echo "... edit_cache"
	@echo "... greeting_es"
	@echo "... greeting_en"
	@echo "... greeting_en.o"
	@echo "... greeting_en.i"
	@echo "... greeting_en.s"
	@echo "... greeting_es.o"
	@echo "... greeting_es.i"
	@echo "... greeting_es.s"
	@echo "... greeting_fr.o"
	@echo "... greeting_fr.i"
	@echo "... greeting_fr.s"
	@echo "... main.o"
	@echo "... main.i"
	@echo "... main.s"
.PHONY : help



#=============================================================================
# Special targets to cleanup operation of make.

# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
	$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

For more information on CMake, see here