\subsection{Feature vs. Platform Checks}

\begin{frame}
  \frametitle{Feature checks}

  \begin{center}
    \huge Probing the outside system\\for capabilities
  \end{center}
\end{frame}

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

\begin{frame}
    \frametitle{What's a ``Feature''}
    Distinctive attribute which may have influence on the final system being built.\\
    \\
    Can be classified in 3 domains:
    \begin{itemize}
        \item Platform features\\
            {\info {library, symbols, functions, type size}}
        \item Compiler features\\
            {\info {variadic templates, constexpr, final, override}}
        \item System dictated features\\
            {\info {no-exceptions, no-rtti, no logging}}
    \end{itemize}
\end{frame}


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

\begin{frame}[containsverbatim]
  \frametitle {Platform specific feature check}

  \textbf{Bad}
\begin{codebox}{CMake}{}
if(IOS OR ANDROID OR UNIX)
  target_compile_definitions(lua PRIVATE HAVE_POSIX_SPAWN)
endif()
\end{codebox}

\textbf{Good}
\begin{codebox}{CMake}{}
check_symbol_exists("posix_spawn" "spawn.h" has_posix_spawn)
if(has_posix_spawn)
  target_compile_definitions(lua PRIVATE HAVE_POSIX_SPAWN)
endif()
\end{codebox}

\end{frame}

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

\begin{frame}[containsverbatim]
  \frametitle {Compiler specific feature checks}

  \textbf{Bad}
\begin{codebox}[minted options={fontsize=\tiny}]{CMake}{}
if(CMAKE_SYSTEM_NAME STREQUAL "QNX")
  target_compile_definitions(my-library
    PRIVATE -DBOOST_THREAD_DONT_USE_CHRONO)
endif()
\end{codebox}

  \textbf{Good}
  \begin{codebox}[minted options={fontsize=\tiny}]{CMake}{}
# (incomplete example, checking for exception support is slightly harder)
check_cxx_source_compile("
  int main() {
    #if !defined(__EXCEPTIONS)
    #error Exceptions not supported.
    #endif
  }" exceptions_supported)

if(NOT exceptions_supported)
  target_compile_definitions(my-library
    PRIVATE -DBOOST_THREAD_DONT_USE_CHRONO)
endif()
\end{codebox}

\end{frame}

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

\begin{frame}[containsverbatim]
  \frametitle {System dictated feature checks}

  \textbf{Bad}
\begin{codebox}[minted options={fontsize=\scriptsize}]{CMake}{}
find_package(Boost)
if(Boost_FOUND)
  add_definition(ENABLE_FEATURE_X)
endif()
\end{codebox}

    \textbf {Good}
\begin{codebox}[minted options={fontsize=\scriptsize}]{CMake}{}
# In product config file
set(ENABLE_FEATURE_X TRUE)

# In project configuration
if(ENABLE_FEATURE_X)
  find_package(Boost REQUIRED)
  add_definition(FEATURE_X_ENABLED)
endif()
\end{codebox}
\end{frame}

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

\begin{frame}
    \frametitle{Functions for configure checks}

    CMake provides an API to check:

    \begin{itemize}
        \item Header existence: {\code{check\_include\_file()}}
        \item Library existence: {\code{check\_library\_exists()}}
        \item Symbol existence: {\code{check\_symbol\_exists()}}
        \item Supported type sizes: {\code{check\_type\_size()}}
    \end{itemize}

    CMake provides an API to write custom checks via:

    \begin{itemize}
        \item {\code{try\_compile()}}
        \item {\code{try\_run()}}
    \end{itemize}

    With {\code configure\_file} you can generate a header file
      enabling required code switches based on the checks.
\end{frame}

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

\note{
    What is Platform check
    What is feature check
    CMAKE system introspection interface
        -What type of checks can be done with CMAKE
        https://cmake.org/Wiki/CMake:How\_To\_Write\_Platform\_Checks
    Pros and Cons
}
