\renewcommand{\FIGREP}{src/build_tools/figures}

\section{Build automation tools}
\label{sec:build_tools}
\intersec{fidis}

\subsection{GNU Make}
\label{sec:gnu-make}
\begin{frame}[t,fragile]
  \frametitle{Build automation tool}
  \framesubtitle{GNU Make}
  \begin{itemize}
    \item Compiling one file by hand is fine, but multiple files become quickly
    cumbersome
    \item Tools have been developed to automatize such process
    \item Here, we will only briefly introduce GNU Make and CMake
  \end{itemize}

  \vfill

  \textbf{GNU Make aka Makefile:}
  \begin{itemize}
    \item The command line \cmd{make} executes shell commands containing in a
    makefile (list of rules)
    \item Rules contain three components:
    \begin{bashcode}
      target: prerequisites
      ->|     recipe
      ->|     ...
    \end{bashcode}
    \item Make keeps track of timestamps: it updates only targets that are
    required
    \item Make can be used for a lot of other things than compiling code!
    \item Just type \cmd{make} in the folder containing the \cmd{Makefile} file
  \end{itemize}
\end{frame}
\note{
   \begin{itemize}  
     \item If you have a large program with many source and/or header files, when you change a file on which others depend, you must recompile all the dependent files. Without a makefile, this is an extremely time-consuming task.   
     \item The makefile contains a list of rules. These rules tell the system what commands you want to be executed. Most times, these rules are commands to compile(or recompile) a series of files. The rules, which must begin in column 1, are in two parts. The first line is called a dependency line and the subsequent line(s) are called actions or commands. The action line(s) must be indented with a tab.  
     \item CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice
   \end{itemize}
 }

 \begin{frame}[t,fragile]
  \frametitle{Makefile}
  \framesubtitle{First naive example}
  \bashfile[title={examples/compilationWithMakefile/Makefile}]{examples/compilationWithMakefile/Makefile}
\end{frame}
\note{
   \begin{itemize}  
     \item First, we can use in the Makefile some variables to assign commands
     \item On the left you have the so-called target: all, ... and following the target, the dependencies %my_exec, etc ... and following the target: the dependencies
     \item The recipes are introduced below the definition target:dependencies
     \item A target might be a binary file that depends on dependencies (source files). On the other hand, a dependency can also be a target that depends on other dependencies:
   \end{itemize}
}

\begin{frame}[t,fragile]
  \frametitle{Makefile}
  \framesubtitle{More refined example}
  \bashfile[title={examples/compilationWithMakefileAdvanced/Makefile}]{examples/compilationWithMakefileAdvanced/Makefile}
\end{frame}

\subsection{GNU CMake}
\label{sec:gnu-cmake}
\begin{frame}[t,fragile]
  \frametitle{Build automation tool}
  \framesubtitle{GNU CMake}

  \textbf{GNU CMake:}
  \begin{itemize}
    \item CMake is an abstraction level above Make
    \item It automatically detects compilers and libraries and generate a
    Makefile (or other tools, \eg{} Ninja)
    \item Suggested workflow:
    \begin{itemize}
      \item Create a build directory and go inside of it
      \begin{bashcode}
        mkdir build
        cd build
      \end{bashcode}
      \item Configure the project
      \begin{bashcode}
        cmake ..
      \end{bashcode}
      \item Compile it
      \begin{bashcode}
        make
      \end{bashcode}
    \end{itemize}
    \item When working, CMake is a very nice tool! Otherwise, it requires some
    knowledge to debug.
  \end{itemize}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{CMake}
  \framesubtitle{Configuration output}

   \begin{consoleoutput}
   $ cmake ..
     -- The C compiler identification is GNU 8.4.0
     -- Check for working C compiler: /ssoft/.../gcc-4.8.5/gcc-8.4.0/bin/gcc
     -- Check for working C compiler: /ssoft/.../gcc-4.8.5/gcc-8.4.0/bin/gcc -- works
     -- Detecting C compiler ABI info
     -- Detecting C compiler ABI info - done
     -- Detecting C compile features
     -- Detecting C compile features - done
     -- Configuring done
     -- Generating done
     -- Build files have been written to: compilationWithCmake/build
   \end{consoleoutput}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{CMake example}
  \framesubtitle{}
  \bashfile[title={examples/compilationWithCmake/CMakeLists.txt}]{examples/compilationWithCmake/CMakeLists.txt}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Compilation}
  \framesubtitle{CMake example}
  \bashfile[title={examples/compilationWithCmakeAdvanced/CMakeLists.txt},
  minted options app={firstline=5,lastline=29}]{examples/compilationWithCmakeAdvanced/CMakeLists.txt}  
\end{frame}

\begin{frame}[exercise]
  \frametitle{Compilation}
  \framesubtitle{Exercise compilationWithCmakeAdvanced}
  \begin{itemize}
    \item Go to the directory \cmd{compilationWithCmakeAdvanced}
    \item Create a directory \cmd{build_gcc} and \cmd{build_intel}
    \item Compile the code, first with \cmd{gcc} compiler in \cmd{build_gcc}, then in \cmd{build_intel} with \cmd{intel} compiler
    \item Use different compilation options modifying the \cmd{CMakeLists.txt} file or using the \cmd{cmake} command line with \cmd{-DCMAKE_C_FLAGS="..."} option
    \item Use \cmd{ifdef MY_MACRO} introduced in \cmd{main.c} using the \cmd{cmake} command line with \cmd{-DSAXPY_USE_MY_MACRO="..."} option or ccmake 
    \item Check the results according to the solution of exercise \cmd{simpleCompilation}
  \end{itemize}
\end{frame}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "../../SCM_slides"
%%% End:
