Step by step guide of the CMake build system of this library
In this guide, we will open up the CMakeLists.txt
file and examine it part by part
Lets begin with ./CMakeLists.txt
, the main file
cmake_minimum_required(VERSION 3.1.0)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-linux-gnueabi-gcc")
set(CMAKE_CC_COMPILER "arm-linux-gnueabi-gcc")
set(CMAKE_CXX_COMPILER "arm-linux-gnueabi-g++")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED true)
Defines the system we are building on and the cmake version we are using Compilers need to be specified so that CMake doesn’t get confused in the Docker container and break, or cry out errors
set(LIBNAME "ev3-cpp-template-wrapper-lib")
project(${LIBNAME} VERSION 2.0.0)
message(STATUS ${CMAKE_CXX_FLAGS})
Defines name of library, the version of the library (it will be changed to 2.5.0 later) and outputs the cmake flags during the build. Even though
message(STATUS ${CMAKE_CXX_FLAGS})
is no longer needed, it is still useful for debugging purposes
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_options(-Os)
Make CMake export compile commands into a file that vscode can process and use as intellisense. This is just for vscode intellisense add_compile_options(-Os)
tells the compiler to build the library while optimizing for size (minimising binary size) so that the robot can load the executable faster
add_library(
${LIBNAME}
STATIC
lib/ev3dev.cpp
lib/blockable/ev3wrapblockable.hpp
lib/button/ev3wrapbutton.cpp
lib/button/ev3wrapbutton.hpp
...
lib/ev3dev.h
lib/ev3wrap.hpp
)
Actually defines the library .a
compilation goal. The files listed here contain the source code of the library.
target_include_directories(
${LIBNAME}
PUBLIC
${PROJECT_SOURCE_DIR}/lib/
${PROJECT_SOURCE_DIR}/lib/blockable/
${PROJECT_SOURCE_DIR}/lib/button/
${PROJECT_SOURCE_DIR}/lib/color/
...
)
Tell CMake where to find the specified files from the previous part (add_library
)
set_target_properties(${LIBNAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/
OUTPUT_NAME "ev3dev-cpp-template-wrapper"
)
Set the output directory and the output file name
set("WRAPPER_EXAMPLES_DIR" ${PROJECT_SOURCE_DIR}/examples)
set("WRAPPER_SCRIPTS_DIR" ${PROJECT_SOURCE_DIR}/scripts)
set("WRAPPER_BIN_DIR" ${PROJECT_BINARY_DIR})
set(WRAPPER_BIN_FINISHED_DIR ${WRAPPER_BIN_DIR}/finished)
set(WRAPPER_BIN_EXAMPLES_DIR ${WRAPPER_BIN_FINISHED_DIR}/examples)
set(EVERYTHING_BUILT_TARGET "EVERYTHING_BUILT_TARGET")
set(LIB_BUILT_TARGET "LIB_BUILT_TARGET")
Define a list of variables that will be used later WRAPPER_EXAMPLES_DIR
: directory containing the example source code WRAPPER_SCRIPTS_DIR
: directory containing the bash scripts used for compiling WRAPPER_BIN_DIR
: directory containing the output binary (build folder) WRAPPER_BIN_FINISHED_DIR
: directory where the final finished binaries will be copied to WRAPPER_BIN_EXAMPLES_DIR
: directory where the finished examples will be copied to EVERYTHING_BUILT_TARGET
, LIB_BUILT_TARGET
: The name of a target. This will be used later
add_custom_target(
${EVERYTHING_BUILT_TARGET}
ALL
)
add_custom_target(
${LIB_BUILT_TARGET}
ALL
)
Add the 2 targets that keep track of:
- If everything, including the executable using the library has been built
- If everything within the library has been built
These targets are important for when we want to measure the binary size of the library once the build is finished.
add_dependencies(${EVERYTHING_BUILT_TARGET} ${LIBNAME})
add_dependencies(${LIB_BUILT_TARGET} ${EVERYTHING_BUILT_TARGET})
Make EVERYTHING_BUILT_TARGET depend on LIBNAME and LIB_BUILT_TARGET depend on EVERYTHING_BUILT_TARGET This is just making sure the targets make sense
add_custom_command(
TARGET ${EVERYTHING_BUILT_TARGET} POST_BUILD
# setting up the directories
COMMAND sudo mkdir -p ${WRAPPER_BIN_FINISHED_DIR}
COMMAND sudo mkdir -p ${WRAPPER_BIN_EXAMPLES_DIR}
# commands for the library itself
COMMAND sudo cp ${WRAPPER_BIN_DIR}/libev3dev-cpp-template-wrapper.a ${WRAPPER_BIN_FINISHED_DIR}/libev3dev-cpp-template-wrapper.a
COMMAND sudo bash ${WRAPPER_SCRIPTS_DIR}/post_build.sh "The-Ev3Wrap-library" 500 ${WRAPPER_BIN_FINISHED_DIR}/libev3dev-cpp-template-wrapper.a 50
)
Make it so that once everything is built, the binaries are copied to the finished folder, and post_build.sh
is run to check its size.
add_subdirectory(examples)
Add another CMake file stored within the examples
folder. That other CMakeLists.txt file manages the compilation of the examples.
We will continue looking at CMakeLists.txt
in the examples
folder here