289 lines
8.2 KiB
TeX
289 lines
8.2 KiB
TeX
|
\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 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{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}
|
|||
|
|
|||
|
% --------------------------------------------------------------------
|