Modern C++ for
Computer Vision and
Image Processing
Lecture 1: Build and Tools
Ignacio Vizzo and Cyrill Stachniss
SW dev ecosystem
1
The compilation
process
What is a compiler?
A compiler is basically... a program.
But not any program.
Is in charge on transforming your horrible
source code into binary code.
Binary code, 0100010001, is the language
that a computer can understand.
2
What is a compiler?
3
Compilation made easy
The easiest compile command possible:
clang++ main.cpp
This will build a program called a.out that
it’s ready to run.
Will be always this easy?
Of course, not.
4
The Compiler: Behind the scenes
The compiler performs 4 distinct actions
to build your code:
1. Pre-process
2. Compile
3. Assembly
4. Link
5
The Compiler: Behind the scenes
6
Compiling step-by-step
1. Preprocess:
clang++ -E main.cpp > main.i
7
Compiling step-by-step
2. Compilation:
clang++ -S main.i
8
Compiling step-by-step
3. Assembly:
clang++ -c main.s
9
Compiling step-by-step
4. Linking:
clang++ main.o -o main
10
Compiling recap
1. clang++ -E main.cpp
2. clang++ -S main.i
3. clang++ -c main.s
4. clang++ main.o
11
Compiling recap
1. clang++ main.cpp
12
Compilation flags
There is a lot of flags that can be passed
while compiling the code
We have seen some already:
-std=c++17, -o, etc.
Other useful options:
Enable all warnings, treat them as errors:
-Wall, -Wextra, -Werror
Optimization options:
-O0 — no optimizations [default]
-O3 or -Ofast — full optimizations
Keep debugging symbols: -g
0
Play with them with Compiler Explorer: https://godbolt.org/
13
Libraries
What is a Library
Collection of symbols.
Collection of function implementations.
14
Libraries
Library: multiple object files that are
logically connected
Types of libraries:
Static: faster, take a lot of space, become part
of the end binary, named: lib*.a
Dynamic: slower, can be copied, referenced by a
program, named lib*.so
Create a static library with
ar rcs libname.a module.o module.o …
Static libraries are just archives just like
zip/tar/…
15
Declaration and definition
Function declaration can be separated from
the implementation details
Function declaration sets up an interface
1 void FuncName (int param);
Function definition holds the
implementation of the function that can
even be hidden from the user
1 void FuncName (int param) {
2 // Implementation details .
3 cout << "This function is called FuncName ! ";
4 cout << "Did you expect anything useful from it?";
5 }
16
Header / Source Separation
Move all declarations to header files (*.hpp)
Implementation goes to *.cpp or *.cc
1 // some_file .hpp
2 Type SomeFunc (... args ...);
3
4 // some_file .cpp
5 # include " some_file .hpp"
6 Type SomeFunc (... args ...) {} // implementation
7
8 // program .cpp
9 # include " some_file .hpp"
10 int main () {
11 SomeFunc (/* args */);
12 return 0;
13 }
17
Just build it as before?
clang++ -std=c++17 program.cpp -o main
Error:
1 /tmp/ tools_main -0 eacf5.o: In function `main ':
2 tools_main .cpp: undefined reference to `SomeFunc ()'
3 clang : error: linker command failed with exit code 1
4 (use -v to see invocation )
18
What is linking?
19
What is linking?
The library is a binary object that contains
the compiled implementation of some
methods
Linking maps a function declaration to its
compiled implementation
To use a library we need:
1. A header file library_api.h
2. The compiled library object libmylibrary.a
20
How to build libraries?
1 folder /
2 --- tools.hpp
3 --- tools.cpp
4 --- main.cpp
Short: we separate the code into modules
Declaration: tools.hpp
1 # pragma once // Ensure file is included only once
2 void MakeItSunny ();
3 void MakeItRain ();
21
How to build libraries?
Definition: tools.cpp
1 # include " tools .hpp"
2 # include <iostream >
3 void MakeItRain () {
4 // important weather manipulation code
5 std :: cout << "Here! Now it rains ! Happy ?\n";
6 }
7 void MakeItSunny () { std :: cerr << "Not available \n"; }
Calling: main.cpp
1 # include " tools .hpp"
2 int main () {
3 MakeItRain ();
4 MakeItSunny ();
5 return 0;
6 }
22
Use modules and libraries!
Compile modules:
c++ -std=c++17 -c tools.cpp -o tools.o
Organize modules into libraries:
ar rcs libtools.a tools.o <other_modules>
Link libraries when building code:
c++ -std=c++17 main.cpp -L . -ltools -o main
Run the code:
./main
23
Build Systems
Building by hand is hard
4 commands to build a simple hello world
example with 2 symbols.
How does it scales on big projects?
Impossible to mantain.
Build systems to the rescue!
24
What are build systems
Tools.
Many of them.
Automate the build process of projects.
They began as shell scripts
Then turn into MakeFiles.
And now into MetaBuild Sytems like CMake.
Accept it, CMake is not a build system.
It’s a build system generator
You need to use an actual build system like Make
or Ninja.
25
What I wish I could write
Replace the build commands:
1. c++ -std=c++17 -c tools.cpp -o tools.o
2. ar rcs libtools.a tools.o <other_modules>
3. c++ -std=c++17 main.cpp -L . -ltools
For a script in the form of:
1 add_library (tools tools.cpp)
2 add_executable (main main.cpp)
3 target_link_libraries (main tools)
26
Use CMake to simplify the build
One of the most popular build tools
Does not build the code, generates files to
feed into a build system
Cross-platform
Very powerful, still build receipt is readable
27
Build a CMake project
Build process from the user’s perspective
1. cd <project_folder>
2. mkdir build
3. cd build
4. cmake ..
5. make
The build process is completely defined in
CMakeLists.txt
And childrens src/CMakeLists.txt, etc.
28
First CMakeLists.txt
1 cmake_minimum_required ( VERSION 3.1) # Mandatory .
2 project ( first_project ) # Mandatory .
3 set( CMAKE_CXX_STANDARD 17) # Use c ++17.
4
5 # tell cmake where to look for *.hpp , *.h files
6 include_directories ( include /)
7
8 # create library " libtools "
9 add_library (tools src/tools.cpp) # creates libtools .a
10
11 # add executable main
12 add_executable (main src/ tools_main .cpp) # main.o
13
14 # tell the linker to bind these objects together
15 target_link_libraries (main tools) # ./ main
29
CMake is easy to use
All build files are in one place
The build script is readable
Automatically detects changes
After doing changes:
1. cd <project_folder>/build
2. make
30
Typical project structure
1 |-- project_name /
2 | |-- CMakeLists .txt
3 | |-- build/ # All generated build files
4 | |-- results / # Executable artifacts
5 | | |-- bin/
6 | | |-- tools_demo
7 | | |-- lib/
8 | | |-- libtools .a
9 | |-- include / # API of the project
10 | | |-- project_name
11 | | |-- library_api .hpp
12 | |-- src/
13 | | |-- CMakeLists .txt
14 | | |-- project_name
15 | | |-- CMakeLists .txt
16 | | |-- tools.hpp
17 | | |-- tools.cpp
18 | | |-- tools_demo .cpp
19 | |-- tests/ # Tests for your code
20 | | |-- test_tools .cpp
21 | | |-- CMakeLists .txt
22 | |-- README .md # How to use your code
31
Compilation options in CMake
1 set( CMAKE_CXX_STANDARD 17)
2
3 # Set build type if not set.
4 if(NOT CMAKE_BUILD_TYPE )
5 set( CMAKE_BUILD_TYPE Debug)
6 endif ()
7 # Set additional flags .
8 set( CMAKE_CXX_FLAGS "-Wall -Wextra ")
9 set( CMAKE_CXX_FLAGS_DEBUG "-g -O0")
-Wall -Wextra: show all warnings
-g: keep debug information in binary
-O<num>: optimization level in {0, 1, 2, 3}
0: no optimization
3: full optimization
32
Useful commands in CMake
Just a scripting language
Has features of a scripting language, i.e.
functions, control structures, variables, etc.
All variables are string
Set variables with set(VAR VALUE)
Get value of a variable with ${VAR}
Show a message message(STATUS "message")
Also possible WARNING, FATAL_ERROR
33
Build process
CMakeLists.txt defines the whole build
CMake reads CMakeLists.txt sequentially
Build process:
1. cd <project_folder>
2. mkdir build
3. cd build
4. cmake ..
5. make -j2 # pass your number of cores here
34
Everything is broken, what
should I do?
Sometimes you want a clean build
It is very easy to do with CMake
1. cd project/build
2. make clean [remove generated binaries]
3. rm -rf * [make sure you are in build folder]
Short way(If you are in project/):
rm -rf build/
35
Use pre-compiled library
Sometimes you get a compiled library
You can use it in your build
For example, given libtools.so it can be
used in the project as follows:
1 find_library (TOOLS
2 NAMES tools
3 PATHS ${ LIBRARY_OUTPUT_PATH })
4 # Use it for linking :
5 target_link_libraries (< some_binary > ${TOOLS })
36
CMake find_path and find_library
We can use an external library
Need headers and binary library files
There is an easy way to find them
Headers:
1 find_path ( SOME_PKG_INCLUDE_DIR include / some_file .hpp
2 <path1 > <path2 > ...)
3 include_directories (${ SOME_PKG_INCLUDE_DIR })
Libraries:
1 find_library ( SOME_LIB
2 NAMES <some_lib >
3 PATHS <path1 > <path2 > ...)
4 target_link_libraries ( target ${ SOME_LIB })
37
find_package
find_package calls multiple find_path and
find_library functions
To use find_package(<pkg>) CMake must
have a file Find<pkg>.cmake in
CMAKE_MODULE_PATH folders
Find<pkg>.cmake defines which libraries and
headers belong to package <pkg>
Pre-defined for most popular libraries,
e.g. OpenCV, libpng, etc.
38
CMakeLists.txt
1 cmake_minimum_required ( VERSION 3.1)
2 project ( first_project )
3
4 # CMake will search here for Find <pkg >. cmake files
5 SET( CMAKE_MODULE_PATH
6 ${ PROJECT_SOURCE_DIR }/ cmake_modules )
7
8 # Search for Findsome_pkg . cmake file and load it
9 find_package ( some_pkg )
10
11 # Add the include folders from some_pkg
12 include_directories (${ some_pkg_INCLUDE_DIRS })
13
14 # Add the executable "main"
15 add_executable (main small_main .cpp)
16 # Tell the linker to bind these binary objects
17 target_link_libraries (main ${ some_pkg_LIBRARIES })
39
cmake_modules/Findsome_pkg.cmake
1 # Find the headers that we will need
2 find_path ( some_pkg_INCLUDE_DIRS include / some_lib .hpp <
FOLDER_WHERE_TO_SEARCH >)
3 message ( STATUS " headers : ${ some_pkg_INCLUDE_DIRS }")
4
5 # Find the corresponding libraries
6 find_library ( some_pkg_LIBRARIES
7 NAMES some_lib_name
8 PATHS <FOLDER_WHERE_TO_SEARCH >)
9 message ( STATUS "libs: ${ some_pkg_LIBRARIES }")
40
Watch for Homeworks
https://youtu.be/hwP7WQkmECE
41
Watch for Homeworks
https://youtu.be/OZEGnam2M9s
42
Suggested Video
“Free software, free society” by Richard
Stallman
https://youtu.be/Ag1AKIl_2GM
43
References
CMake Documentation
cmake.org/cmake/help/v3.10/
GCC Manual
gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/
Clang Manual
releases.llvm.org/10.0.0/tools/clang/docs/index.html
44