3.3. Workflow¶
There is a nice feature in CMake that can greatly simplify a
developer’s workflow: The native build tool will watch
the CMake sources for changes and re-run the configure step automatically. In
command-line terms it means that you have to run cmake -H. -B_builds
only
once, you don’t need to run configure again after modification of
CMakeLists.txt - you can simply use cmake --build
.
3.3.1. Makefile example¶
Back to the example with message
:
# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(foo)
add_executable(foo foo.cpp)
message("Processing CMakeLists.txt")
Examples on GitHub
Generate the Makefile:
[minimal-with-message]> cmake -H. -B_builds
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /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: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Processing CMakeLists.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /.../minimal-with-message/_builds
And run build:
[minimal-with-message]> cmake --build _builds
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o
[100%] Linking CXX executable foo
[100%] Built target foo
The executable foo
is created from the foo.cpp
source. The Make tool knows that if
there are no changes in foo.cpp
then there is no need to build and link executable again.
If you run build again there will be no compile and link stage:
[minimal-with-message]> cmake --build _builds
[100%] Built target foo
Let’s “modify” the foo.cpp
source:
[minimal-with-message]> touch foo.cpp
[minimal-with-message]> cmake --build _builds
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o
[100%] Linking CXX executable foo
[100%] Built target foo
Make detects that the executable foo
is out-of-date and rebuilds it. Well, that’s
what build systems are designed for :)
Now let’s “change” CMakeLists.txt. Do we need to run cmake -H. -B_builds
again? The answer is NO - just keep using cmake --build _builds
.
CMakeLists.txt is added as a dependent file to the Makefile:
[minimal-with-message]> touch CMakeLists.txt
[minimal-with-message]> cmake --build _builds
Processing CMakeLists.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /.../minimal-with-message/_builds
[100%] Built target foo
You see Processing CMakeLists.txt
, Configuring done
and
Generating done
indicating that the CMake code is parsed again and a new Makefile is
generated. Since we didn’t change the way the target foo
is built (like adding any
new build flags or compile definitions) there are no compile/link stages.
If you “modify” both the CMake and C++ code you will see the full configure/generate/build stack of commands:
[minimal-with-message]> touch CMakeLists.txt foo.cpp
[minimal-with-message]> cmake --build _builds
Processing CMakeLists.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /.../minimal-with-message/_builds
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o
[100%] Linking CXX executable foo
[100%] Built target foo
3.3.2. Visual Studio example¶
The same is true for other generators as well. For example when you touch
CMakeLists.txt and try to run foo
target in Visual Studio:
The IDE will notify you about an update of the project. You can click “Reload All” to reload the new configuration:
3.3.3. UML activity diagram¶
Activity diagram for the workflow described above:
3.3.4. Suspicious behavior¶
If your workflow doesn’t match the configure-once approach then it may be a
symptom of wrongly written CMake code. Especially when you have to run
cmake -H. -B_builds
twice or when cmake --build _builds
doesn’t detect
updates that have been made to the CMake code.
CMake issue