\subsection{The CMake processing steps}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Projects and targets}

  \begin{center}
    \huge Defining what to build
  \end{center}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{The CMake Process}

  \begin{columns}
    \begin{column}{0.425\textwidth}
      CMake has two main steps:
      \begin{itemize}
      \item Configure step.
      \item Generate step.
      \end{itemize}
    \end{column}

    \begin{column}{0.575\textwidth}
      \begin{figure}
        \centering
        \includegraphics[width=.8\textwidth,keepaspectratio]{images/cmake-simple-flowchart.png}
        \caption*{\tiny 2017 © Jeff Preshing \url{http://preshing.com/20170511/how-to-build-a-cmake-based-project/}}
      \end{figure}
    \end{column}
  \end{columns}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{$1^{st}$ step - Configuration}

  In the \emph{configure} step CMake processes all the input given to
  it, via \texttt{CMakeLists.txt}, and creates an internal
  representation of the build to be performed. \texttt{CMakeCache.txt}
  is generated at this step.

  \vspace{1em}

  The end of this step is expressed by \texttt{"Configuring done"}
  message from CMake.
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{$2^{nd}$ step - Generation}

  In the \emph{generate} step CMake will produce native build tool
  files e.g. Visual Studio solution files, XCode project files, Ninja
  build files etc.

  \vspace{1em}

  The end of this step is expressed by \texttt{"Generating done"}
  message from CMake.
\end{frame}

% --------------------------------------------------------------------

\subsection{About targets}

\begin{frame}
  \frametitle{Targets and dependency propagation}

  \begin{center}
    \huge Targets and their dependencies
  \end{center}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Targets}

  A CMake-based buildsystem is organized as a set of high-level
  logical \emph{targets}.

  \vspace{1em}

  Each target either corresponds to an executable or library, or is a custom
  target containing custom commands.

  \vspace{1em}

  \begin{codebox}{CMake}{}
    add_library(archive archive.cpp zip.cpp lzma.cpp)
    add_executable(zipapp zipapp.cpp)
    target_link_libraries(zipapp archive)
  \end{codebox}
      
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Custom Target and Dependencies}
  
  Example with custom targets:

  \vspace{1em}

  \begin{codebox}{CMake}{}
    add_custom_command(OUTPUT output.file
      COMMAND generator 
        --in ${CMAKE_CURRENT_SOURCE_DIR}/input.file 
        --out output.file
      DEPENDS input.file
      COMMENT "This is an example invocation of a generator"
      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

    add_custom_target(my-target 
      DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/output.file)
  \end{codebox}
\end{frame}

\begin{frame}[containsverbatim]
    \frametitle{Transitive Usage Requirements}

    The usage requirements of a target can transitively propagate to
    dependents.

    \vspace{1em}

    The {\code{target\_link\_libraries()}} command has
    \texttt{PRIVATE}, \texttt{INTERFACE}, and \texttt{PUBLIC} keywords
    to control the propagation.
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
    \frametitle{Transitive Usage Requirements}

    A dependency should be specified in a use of
    {\code{target\_link\_libraries()}} with the:

    \begin{itemize}
    \item \texttt{PRIVATE} keyword, if it is used \emph{only} by the
      implementation of a library, and not in its public header files.
    \item \texttt{PUBLIC} keyword, if a dependency is additionally
      used in the header files of a library (e.g. any header
      inclusion).
    \item \texttt{INTERFACE} keyword, if is \emph{not} used by the
      implementation of a library, but only by its public header
      files.
    \end{itemize}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Transitive Usage Requirements – Example}

\begin{codebox}{CMake}{}
add_library(liba a.cpp)
target_compile_definitions(liba INTERFACE USING_LIB_A)

add_library(libb b.cpp)
target_compile_definitions(libb INTERFACE USING_LIB_B)

add_library(libc c.cpp)
target_link_libraries(libc PUBLIC liba PRIVATE libb)
# libc is compiled with -DUSING_LIB_A and -DUSING_LIB_B

add_executable(app main.cpp)
target_link_libraries(app libc)
# app is compiled with -DUSING_LIB_A
\end{codebox}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Targets – Modifier functions}

  You should use the following functions to control your targets:

  \begin{itemize}
  \item {\code{target\_include\_directories()}} – adds directories to
    the include search path.
  \item {\code{target\_compile\_definitions()}} – adds pre-processor
    definitions.
  \item {\code{target\_compile\_options()}} – adds compiler options
    (\texttt{-Wall, /bigobj}).
  \item {\code{target\_compile\_features()}} – adds necessary compiler
    features (\texttt{cxx\_constexpr, cxx\_variadic\_templates}).
  \item {\code{target\_sources()}} – adds more source files to the
    target.
  \item {\code{target\_link\_libraries()}} – add library dependency.
  \end{itemize}
\end{frame}

% --------------------------------------------------------------------

\subsection{Preparing for packaging}

\begin{frame}
  \frametitle{Locating packages}

  \begin{center}
    \huge Preparing the project for packaging
  \end{center}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{CMake packages}
  Packages provide dependency information to CMake.

  \vspace{1em}

  Packages are found with the {\code{find\_package()}} command.

  \vspace{1em}

  The result of using {\code{find\_package()}} is either a set of
  \texttt{IMPORTED} targets, or a set of variables
  e.g. \texttt{<package>\_FOUND}, \texttt{<package>\_INCLUDE\_DIRS},
  \texttt{<package>\_LIBRARIES}.
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Packages – Example}
  CMake provides direct support for two forms of packages:
  \begin{itemize}
  \item \texttt{CONFIG}-file packages (the new way).
  \item Find-\texttt{MODULE} packages (prioritized for backwards-compat).
  \end{itemize}

\begin{codebox}{CMake}{}
# CMake provides a Boost find-module
find_package(Boost 1.60.0 MODULE REQUIRED)

# Qt Project provides a Qt5 package config file.
find_package(Qt5Core 5.9.0 CONFIG REQUIRED
                           COMPONENTS Widgets)

# Use pkg-config via the LibXml2 find-module
find_package(LibXml2 MODULE REQUIRED)
\end{codebox}
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Packages – Config-file}

  A config-file package the recommended CMake package type.

  \vspace{1em}

  The config-file package consists of a set of files provided by
  upstreams for downstreams to use.

  \vspace{1em}

  The Qt Project doesn't use CMake as their own build system, but
  they do provide a config-file package for CMake users.
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Packages -- Find-module}

  A find-module is needed when the upstream is not built with CMake,
  or is not CMake-aware enough to otherwise provide a package
  configuration file.

  \vspace{1em}

  The find-module is a file with a set of rules for finding the
  required pieces of a dependency, primarily header files and
  libraries e.g. \texttt{FindBoost.cmake}.
\end{frame}

% --------------------------------------------------------------------

\begin{frame}[containsverbatim]
  \frametitle{Packages – Config-file continued}

  A config-file package can be used in two ways:
  \begin{itemize}
  \item to find a configured project that is already part of the
    build.
  \item to import an installed package.
  \end{itemize}

  \vspace{1em}

  The process of creating a config-file package using CMake commands
  ({\code{configure\_package\_config\_file()}},
  {\code{write\_basic\_package\_version\_file()}}, {\code{install()}},
  {\code{export()}}) is quite verbose, and error prone.
\end{frame}

% --------------------------------------------------------------------
