Example Project using CMake Style Structure
This chapter provides an overview of a project structured in a style that is common to CMake projects that uses CMaize as its build system.
Project Overview
ExampleCMakeProject
is a simple C++ project that consists of the following
components:
The
travel_cost_utils
library that contains some simple arithmetic calculations for use in calculating travel costs.The
travel_cost_calc
executable that calculates travel cost for a set of predefined values using functions intravel_cost_utils
.The
test
directory that contains some tests written using the Catch2 library that test thattravel_cost_utils
works properly.
Here is the file structure of the project:
ExampleCMakeProject
├── CMakeLists.txt
├── cmake
│ └── get_cmaize.cmake
├── travel_cost_utils
| ├── travel_cost_utils.cpp
| └── travel_cost_utils.hpp
├── travel_cost_calc
| └── travel_cost_calc.cpp
└── test
└── test_travel_cost_utils.cpp
This structure is commonly found in CMake projects. A subdirectory is created for each executable and library. A subdirectory is also created the project’s tests.
Creating the CMakeLists.txt File
Here we will cover the contents of the CMakeLists.txt
file at the root of
the project.
The Basics
First we must start with the basics. We need to declare the minimum required version of CMake, the name and version of the project, the language of the project, and the C++ standard of the project.
# Declare minimum version required
cmake_minimum_required(VERSION 3.13.4)
# Declare project name and version
project(example_cmake_project VERSION 1.0)
# Set the project language
set(LANGUAGE CXX)
# Set C++ standard
set(CMAKE_CXX_STANDARD 14)
Including CMaize
We also need to include CMaize. This is described more in Automatically Downloading and Including CMaize.
# Include CMaize automatically
include("${PROJECT_SOURCE_DIR}/cmake/get_cmaize.cmake")
Adding the TravelCostUtils Library
Now we will add our travel_cost_utils
library. We need to specify the target
name, its source directory, and its include directory:
# Add our travel_cost_utils library
cpp_add_library(
travel_cost_utils
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/travel_cost_utils"
INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/travel_cost_utils"
)
Adding the TravelCostCalc Executable
Here we add our travel_cost_calc
executable. We simply need to specify
the target name, its source directory, and its dependencies:
# Add the travel_cost_calc executable
cpp_add_executable(
travel_cost_calc
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/travel_cost_calc"
DEPENDS travel_cost_utils
)
Adding Tests
Now we will add our tests. First, we’ll create an if
block so that our tests
are only built if the BUILD_TESTING
argument is set to ON
(or some other
“truthy” value):
if("${BUILD_TESTING}")
# Stuff for building tests will go here
endif()
Next we will add a target for finding or building the Catch2 unit testing framework. We need to do the following:
Create a target name for it (
Catch2
in this case)Point to its GitHub repository URL using the
URL
keywordSpecify the target we want to build in the repository using the
BUILD_TARGET
keywordSpecify the name we want to use to find this library using the
FIND_TARGET
keywordAdditionally we will pass in the
BUILD_TESTING=OFF
argument so that no tests are built for the library. Passing in arguments is accomplished by using theCMAKE_ARGS
keyword.
if("${BUILD_TESTING}")
# Get the Catch2 unit testing framework
cpp_find_or_build_dependency(
Catch2
URL github.com/catchorg/Catch2
BUILD_TARGET Catch2
FIND_TARGET Catch2::Catch2
CMAKE_ARGS BUILD_TESTING=OFF
)
endif()
Finally, to add our tests, we just need to specify the source directory and the
tests dependencies (which in this case are our TravelCostUtils
library and
the Catch2
testing framework). We will put our tests and their dependencies
within an if
block so that they are only built if users set the
BUILD_TESTING
argument to ON
(or some other “truthy” value).
# Build tests if build testing is enabled
if("${BUILD_TESTING}")
# Get the Catch2 unit testing framework
cpp_find_or_build_dependency(
Catch2
URL github.com/catchorg/Catch2
BUILD_TARGET Catch2
FIND_TARGET Catch2::Catch2
CMAKE_ARGS BUILD_TESTING=OFF
)
# Add the tests
cpp_add_tests(
travel_cost_utils_test
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/test"
DEPENDS travel_cost_utils Catch2::Catch2
)
endif()
Note
Here we use Catch2::Catch2 to find the Catch2 test framework as this is the name of the target exported by Catch2.
Building the Project
The project can be built by running the following commands at the root of the project:
# Create the build system
cmake -B build
# Build the project
cmake --build build
Running the Executable and Tests
We can run our executable and our tests with the following commands:
# Run the executable
./build/travel_cost_calc
# Run the tests
./build/travel_cost_utils_test
Final Project Code
This final example project can be viewed and downloaded here.