Files for a 10-minute presentation introducing CMake. The slides are created with org-reveal and available here (hit Space or N to move to the next slide).
The main part of the presentation is a live demonstration of setting up a minimal C++ project that uses CMake. The end result of the demonstration is the stuff in example and it roughly consists of the following steps.
Create a directory for the example project containing main.cpp
#include <iostream>
int main() {
std::cout << "Hello, world\n";
}and CMakeLists.txt
cmake_minimum_required(VERSION 3.9.4)
project(HelloWorld)
add_executable(hello main.cpp)Run cmake . in the new directory followed by make. This should work and generate an
executable.
Add two more source files, modify main.cpp and update CMakeLists.txt. See
0af6fcf.
-
strings.hpp#include <string> extern std::string hello_world;
-
strings.cpp#include "strings.hpp" std::string hello_world = "Hello, world";
-
main.cppdiff@@ -1,5 +1,7 @@ #include <iostream> +#include "strings.hpp" + int main(int argc, char* argv[]) { - std::cout << "Hello, world\n"; + std::cout << hello_world << "\n"; }
-
CMakeLists.txtdiff@@ -1,3 +1,4 @@ cmake_minimum_required(VERSION 3.9.4) project(HelloWorld) -add_executable(hello main.cpp) +file(GLOB SOURCES "*.cpp") +add_executable(hello ${SOURCES})
CMake will find new source files automatically now. I should note that this practice is recommended against:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
Demonstrate that the generated makefile will only perform the necessary steps to rebuild
the hello target by touching main.cpp, strings.cpp, and strings.hpp and running
make each time.
Move all sources into a subdirectory (src/) and adjust CMakeLists.txt. See
f462fc9. Run make.
Switch to out-of-place builds. We need to remove all files that CMake generated in the project root directory.
rm -rf CMakeCache.txt CmakeFiles/ cmake_install.cmake MakefileThen we can create a new directory and build there.
mkdir build
cd build
cmake ..
makeIt turns out we aren't using any compiler warnings. We can check with what options the compiler is invoked like this:
make clean
make VERBOSE=1That's bad. Commit a3478ca enables some compiler warnings by changing
CMakeLists.txt like this:
@@ -1,4 +1,13 @@
cmake_minimum_required(VERSION 3.9.4)
project(HelloWorld)
+
+# Enable some warnings. See <https://stackoverflow.com/a/14235055>.
+if (CMAKE_COMPILER_IS_GNUCC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
+endif (CMAKE_COMPILER_IS_GNUCC)
+if (MSVC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
+endif (MSVC)
+
file(GLOB SOURCES "src/*.cpp")
add_executable(hello ${SOURCES})Confirm that this worked by running make VERBOSE=1.
It also turns out the C++ standard we are using is just the compiler's default (I think).
Explicitly specify a C++ standard by adding set(CMAKE_CXX_STANDARD 14) to
CMakeLists.txt. See bf5c30a.
Confirm that this worked by running make VERBOSE=1 again.
Show how to do debug and release builds. Remove all the generated files in build/ and
create new subdirectories first:
rm -r *
mkdir debug release-
To do a release build:
cd release/ cmake -DCMAKE_BUILD_TYPE=Release ../../ make VERBOSE=1 # check the output to confirm optimization is enabled
This added
-O3and-DNDEBUGto the compiler options when I tried it. -
To do a debug build:
cd ../debug/ cmake -DCMAKE_BUILD_TYPE=Debug ../../ make VERBOSE=1 # check the output to confirm optimization is enabled
This added
-gto the compiler options.
After performing the changes of commit 150287f, rerun make.