\documentclass[aspectratio=169]{beamer}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphics}
\usepackage{graphicx}
\usepackage{verbatim}
\usepackage{plantuml}
\usepackage{listings}
\usepackage{csquotes}
\usepackage{multicol}
\usepackage{menukeys}


% Style related code
%
\setbeamerfont{footnote}{size=\tiny}

% Code block style
%
\lstset{
  basicstyle=\footnotesize\ttfamily,
  columns=fullflexible,
  frame=single,
  numbers=left
}

\title{Workshop Modern C++ build environment}
\author{Bart Beumer (bart.beumer@alten.nl)}
\institute{Alten}
\date{2025-07-29}


\begin{document}



\begin{frame}
\titlepage
\end{frame}


\begin{frame}{Rationale}
Using modern tools in combination with C \& C++ we can describe the build environment, 3rd party libraries and executables to build.

We will be able to create a highly reproducable build environment regardless of the OS running on the developer PC (as long as it can run docker).

\vspace{5mm}

This workshop aims to demonstrate how to create this build environment, how to use the tools, introduce ourselves to this way of working using included demonstration projects.
\end{frame}


\begin{frame}{Tools}
We will be using a combination of tools, each having their own purpose.
\begin{itemize}
 \item Dev containers \footnote{\url{https://containers.dev/}}

 \begin{quote}
  A development container (or dev container for short) allows you to use a container as a full-featured development environment.
 \end{quote}

 \item Conan \footnote{\url{https://conan.io/faq}}

 Open source, decentralized and multi-platform package manager.

 \item CMake \footnote{\url{https://cmake.org/about/}}

 \begin{quote}
  ... an open source, cross-platform family of tools designed to build, test, and package software.
 \end{quote}
\end{itemize}
\end{frame}


\begin{frame}{Dev containers}
Solves the problem of having an encapsulated environment containing all tools, files, configuration that makes up the development environment.

\vspace{5mm}

Supported by multiple tools like:
\begin{itemize}
 \item Visual Studio Code \footnote{\url{https://containers.dev/supporting}}
 \item IntelliJ IDEA \footnote{\url{https://blog.jetbrains.com/idea/2024/07/using-dev-containers-in-jetbrains-ides-part-1/}}
 \item GitHub codespaces \footnote{\url{https://docs.github.com/en/codespaces/about-codespaces/what-are-codespaces}}
\end{itemize}
\end{frame}

\begin{frame}{Dev containers}
 We need the following files:
 \begin{itemize}
  \item Dockerfile
  \item devcontainer.json
 \end{itemize}

\end{frame}


\begin{frame}{Dev containers}
 Using docker compose we create the entire container.
 \lstinputlisting[keepspaces,firstline=1, firstnumber=1]{../.devcontainer/Dockerfile}
\end{frame}


\begin{frame}{Dev containers}
 A devcontainer.json contains metadata used by tools.
 \lstinputlisting[firstline=1, firstnumber=1]{../.devcontainer/devcontainer.json}
\end{frame}


\begin{frame}{Dev containers}
We will experiment with these files during the workshop.
\end{frame}


\begin{frame}{Conan}
\begin{quotation}
 Conan is a package manager for C and C++ which aims to solve some very common and difficult challenges.\footnote{\url{https::/conan.io/faq}}
\end{quotation}

\begin{itemize}
 \item Conveniently depend on 3rd party packages and use them.
 \item Automates the process of downloading, building \& deploy for further use.
 \item Provide a mechanism to use libraries.
\end{itemize}
\end{frame}


\begin{frame}{Conan}
A simple text file can be used to configure dependencies on packages.
\lstinputlisting[language=make]{../conanfile.txt}
\end{frame}


\begin{frame}{Conan}
We will experiment with these files during the workshop.
\end{frame}


\begin{frame}{CMake}
 \begin{quote}
  CMake is an open source, cross-platform family of tools designed to build, test, and package software. CMake gives you control of the software compilation process using simple independent configuration files. Unlike many cross-platform systems, CMake is designed to be used in conjunction with the native build environment.
  \footnote{\url{https://cmake.org/about/}}
 \end{quote}
 \begin{itemize}
  \item Good documentation and tutorials provided.\footnote{\url{https://cmake.org/cmake/help/latest/guide/tutorial/index.html}}
  \item Tools run locally on a system.
\end{itemize}
\end{frame}


\begin{frame}{CMake}
Using files we can describe libraries, executables, the (external) dependencies they have.
\lstinputlisting[language=make]{../src/hello_world/CMakeLists.txt}
\end{frame}


\begin{frame}{CMake}
We will experiment with these files during the workshop.
\end{frame}


\begin{frame}{Workshop}
\begin{multicols}{2}
Lets start with opening our IDE and our project folder.

\includegraphics[width=0.45\textwidth]{vscode_empty}

Quickly after opening the folder we get the following question:

\includegraphics[width=0.45\textwidth]{vscode_folder_contains_devcontainer}

VS Code will build the container if needed and start using it.
\end{multicols}
\end{frame}


\begin{frame}{Workshop}
The dev container has been built, now we need to let conan work and fetch and build dependencies.

\vspace{5mm}

\keys{CTRL + SHIFT + P}  ``conan install''

\vspace{5mm}

\includegraphics[width=0.75\textwidth]{vscode_conan_install}
\end{frame}


\begin{frame}{Workshop}
\begin{multicols}{2}
We can now use CMake to build our software.
\includegraphics[height=0.65\textheight]{vscode_conan_done_cmake}
\begin{itemize}
 \item configure
 \item build
 \item debug/launch
\end{itemize}
\end{multicols}
\end{frame}


\begin{frame}{Workshop}
Continuing with theory
\end{frame}

\begin{frame}[fragile]{Conan: important commands}
\begin{verbatim}
pip install conan
\end{verbatim}
We use the python package manager to install conan. (part of Dockerfile)

\begin{verbatim}
conan profile detect
\end{verbatim}
We let conan detect compilers and tools for which it can use. (part of Dockerfile)

\begin{verbatim}
conan install
\end{verbatim}
While in the project working directory, download packages, compile them, generate CMake environment. (was run using vs code)

After that we can use CMake as we would normally.
\end{frame}


\begin{frame}{CMake}
\end{frame}


\begin{frame}{CMake: The basics}
  \lstinputlisting[language=make]{../src/hello_world/CMakeLists.txt}
\end{frame}


\begin{frame}{CMake: The basics}
  \lstinputlisting[language=make,firstline=1,lastline=2]{../src/hello_world/CMakeLists.txt}
  \begin{itemize}
    \item Sets the minimum required version of cmake for a project.
    \item Sets behavior of CMake as it was at a certain version (set policies)\footnote{\url{https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html}}
  \end{itemize}

  \vspace{5mm}

  A mechanism to provide backwards compatibility while allowing future versions to change behavior of commands.
\end{frame}


\begin{frame}[fragile]{CMake: The basics}
  \lstinputlisting[language=make,firstline=2, firstnumber=2, lastline=9]{../src/hello_world/CMakeLists.txt}
  \begin{itemize}
    \item ``project''

    Used to set the PROJECT\_NAME variable.

    \item ``add\_executable''

    Adding executable by specifying the executable name and the source files.
  \end{itemize}
\end{frame}



\begin{frame}[fragile]{CMake: The basics}
  \lstinputlisting[language=make,firstline=9, firstnumber=9, lastline=18]{../src/hello_world/CMakeLists.txt}
  \begin{itemize}
    \item ``set\_property''

    Enables us to set properties like language standard to use (C++, CUDA, ...)
  \end{itemize}
\end{frame}


\begin{frame}{CMake: The basics, library}
  \lstinputlisting[language=make, firstline=3,firstnumber=3, lastline=21]{../src/awesome_log/CMakeLists.txt}
\end{frame}


\begin{frame}{CMake: The basics, library}
  \lstinputlisting[language=make,firstline=5,firstnumber=5,lastline=11]{../src/awesome_log/CMakeLists.txt}

  Similar to ``add\_executable'' we can create a library, specifying the name of the library and the sources that form it.
\end{frame}

\begin{frame}{CMake: The basics, library}
  \lstinputlisting[language=make,firstline=18,firstnumber=18,lastline=21]{../src/awesome_log/CMakeLists.txt}

  Add include directories, for both creating the target itself AND targets depending on this target.

  \vspace{5mm}

  No need for consumers of the library to set include paths, they inherit from this library target.
\end{frame}


\begin{frame}{Using 3rd-party packages}
\end{frame}


\begin{frame}{Conan: 3rd-party packages}
\lstinputlisting[language=make]{example_conan.txt}
\begin{itemize}
 \item ``[requires]''

 Declare the libraries that we want to use in our project.

 \item ``[generators]''

 Tell Conan to generate files for given build system
\end{itemize}
\end{frame}


\begin{frame}{Conan: 3rd-party packages the python way}
\lstinputlisting[language=make]{example_conan_py.txt}
\end{frame}


\begin{frame}{CMake: Using 3rd-party packages}
 \lstinputlisting[language=make]{../src/example_boost/CMakeLists.txt}
\end{frame}



\begin{frame}{CMake, 3rd-party packages}
\lstinputlisting[language=make, firstline=2,firstnumber=2,lastline=4]{../src/example_boost/CMakeLists.txt}
Find a package (usually provided by something external to the project), and load its package-specific details.\footnote{\url{https://cmake.org/cmake/help/latest/command/find_package.html}}

\lstinputlisting[language=make, firstline=15,firstnumber=15,lastline=18]{../src/example_boost/CMakeLists.txt}
Using exposed target names we can use those packages.
\begin{itemize}
 \item Affects libraries linked to target.
 \item Affects include paths to look for headers.
\end{itemize}
\end{frame}



\begin{frame}[fragile]{CMake: Testing}
\begin{verbatim}
enable_testing()
\end{verbatim}
Use enable\_testing() at the top level CMakeLists.txt to enable cmake to generate things needed to support testing\footnote{\url{https://cmake.org/cmake/help/latest/command/enable_testing.html}}.

\begin{verbatim}
add_test()
\end{verbatim}
Use add\_test() inside your CMakeLists.txt to register the test\footnote{\url{https://cmake.org/cmake/help/latest/command/add_test.html}}.

\begin{verbatim}
ctest
\end{verbatim}
Commandline application to run all registered tests\footnote{\url{https://cmake.org/cmake/help/latest/manual/ctest.1.html}}.
\end{frame}

\begin{frame}
 Worshop time! Suggestions:
 \begin{itemize}
  \item Play around in the environment, have a look at some of the projects.
  \item Try and add a 3rd party package and use it (fmt, ...)
  \item Use a different compiler.
  \item Add a tool to your image (valgrind, ...).
 \end{itemize}
\end{frame}

\end{document}
