\label{doc_decisions_4_decided_header_include_md_md_doc_decisions_4_decided_header_include}%
\Hypertarget{doc_decisions_4_decided_header_include_md_md_doc_decisions_4_decided_header_include}%
 \hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2071}{}\doxysection{Problem}\label{doc_decisions_4_decided_header_include_md_autotoc_md2071}
In C you can include a header file with


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}header.h"{}}}

\end{DoxyCode}


or


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <header.h>}}

\end{DoxyCode}


In the C standard, section 6.\+10.\+2, paragraphs 2 to 4 state\+:

\begin{quote}
2. A preprocessing directive of the form


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <h-\/char-\/sequence>} \textcolor{keyword}{new}-\/line}

\end{DoxyCode}


searches a sequence of implementation-\/defined places for a header identified uniquely by the specified sequence between the {\ttfamily $<$} and {\ttfamily $>$} delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-\/defined.


\begin{DoxyEnumerate}
\item A preprocessing directive of the form
\end{DoxyEnumerate}


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}q-\/char-\/sequence"{}} \textcolor{keyword}{new}-\/line}

\end{DoxyCode}


causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the {\ttfamily "{}} delimiters. The named source file is searched for in an implementation-\/defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <h-\/char-\/sequence>} \textcolor{keyword}{new}-\/line}

\end{DoxyCode}


with the identical contained sequence (including {\ttfamily $>$} characters, if any) from the original directive.


\begin{DoxyEnumerate}
\item A preprocessing directive of the form
\end{DoxyEnumerate}


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include pp-\/tokens new-\/line}}

\end{DoxyCode}


(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms. The method by which a sequence of preprocessing tokens between a {\ttfamily $<$} and a {\ttfamily $>$} preprocessing token pair or a pair of {\ttfamily "{}} characters is combined into a single header name preprocessing token is implementation-\/defined.

\end{quote}
\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2072}{}\doxysubsection{Definitions\+:}\label{doc_decisions_4_decided_header_include_md_autotoc_md2072}

\begin{DoxyItemize}
\item h-\/char\+: any member of the source character set except the new-\/line character and {\ttfamily $>$}
\item q-\/char\+: any member of the source character set except the new-\/line character and {\ttfamily "{}} 
\end{DoxyItemize}

In short, the whole search process of the {\ttfamily \#include} mechanism is implementation-\/defined. However, because {\ttfamily \#include} works (mostly) like a literal copy-\/paste, deciding between {\ttfamily \char`\"{}\char`\"{}} and {\ttfamily $<$$>$} within a public header file can affect user code.\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2073}{}\doxysection{Assumptions}\label{doc_decisions_4_decided_header_include_md_autotoc_md2073}

\begin{DoxyItemize}
\item Modern Compilers work like \href{https://gcc.gnu.org/onlinedocs/cpp/header-files/search-path.html}{\texttt{ GCC}}\+:
\begin{DoxyItemize}
\item {\ttfamily \#include \char`\"{}\mbox{[}header\mbox{]}\char`\"{}} treats {\ttfamily \mbox{[}header\mbox{]}} as file path relative to the current file (as defined by the standard, if such a file doesn\textquotesingle{}t exist there is a fallback to the {\ttfamily $<$$>$} behavior)
\item {\ttfamily \#include $<$\mbox{[}header\mbox{]}$>$} treats {\ttfamily \mbox{[}header\mbox{]}} as file path relative to one of the pre-\/defined include-\/paths
\end{DoxyItemize}
\item We can write a tool that enforces all rules in this decision, in such a way that new contributors can learn the rules as they go.
\end{DoxyItemize}\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2074}{}\doxysection{Considered Alternatives}\label{doc_decisions_4_decided_header_include_md_autotoc_md2074}

\begin{DoxyItemize}
\item Let developers decide\+:

This would just create inconsistent code.
\item Put all headers into one directory and use the same relative layout as will be installed. Then use {\ttfamily \char`\"{}\char`\"{}}\+:

This makes for an inconvenient development experience. It is also pretty hard to achieve for plugins and private headers would clutter the include-\/directory.
\item Only use {\ttfamily \#include $<$$>$} and add everything to include path.

This makes the build setup more complicated. It also makes it much easier to accidentally include a non-\/installed header in an installed one.
\end{DoxyItemize}\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2075}{}\doxysection{Decision}\label{doc_decisions_4_decided_header_include_md_autotoc_md2075}
The rules for including headers are\+:


\begin{DoxyItemize}
\item To include a private non-\/installed header (i.\+e., a file that is only available in the source repo) use\+: 
\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}./header.h"{}}}
\DoxyCodeLine{\textcolor{comment}{// or}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}./subdir/header.h"{}}}

\end{DoxyCode}
 It should not be necessary, to include a private non-\/installed header from another directory. This ensures that libraries only use their own private APIs. Going up one (or more) directories, but staying in the same library would be okay, but is considered an indication of bad code structure. A library can always be restructured to avoid needing a {\ttfamily \#include "{}../}.
\item Internal non-\/installed headers (i.\+e., a file that is not installed, but contains APIs exposed to other libraries within Elektra) can be included with 
\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <internal/somelib.h>}}
\DoxyCodeLine{\textcolor{comment}{// or}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <internal/somelib/header.h>}}

\end{DoxyCode}
 Since these internal headers are not installed, they must only be included from other headers that are not installed or from code files.
\item Installed headers are included with their full path as if they are installed already\+: 
\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <elektra/somelib.h>}}
\DoxyCodeLine{\textcolor{comment}{// or}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <elektra/somelib/header.h>}}

\end{DoxyCode}

\item System headers or headers for external libraries are included with\+: 
\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <stdlib.h>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <dbus/dbus.h>}}
\DoxyCodeLine{\textcolor{comment}{// etc.}}

\end{DoxyCode}

\end{DoxyItemize}

Only {\ttfamily build/include}, which is a copy of {\ttfamily src/include} after CMake processing, is added to the include path. The entire {\ttfamily build/include/elektra} directory is installed as-\/is, with the exact same directory structure and without any further processing.

This is enough for {\ttfamily \#include $<$$>$}s to work.

But we will create an additional script that enforces that {\ttfamily internal/$\ast$} headers are not included from headers in {\ttfamily src/include/elektra}. We will also enforce that the path in a {\ttfamily \#include \char`\"{}\char`\"{}} always starts with a {\ttfamily ./} and does not contain any {\ttfamily /../}.

These include-\/rules do not apply to tests. Tests can include anything (including {\ttfamily .c} files) from anywhere within the code base to allow testing private APIs.\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2076}{}\doxysection{Rationale}\label{doc_decisions_4_decided_header_include_md_autotoc_md2076}
The decision highlights the difference between installed and non-\/installed headers. The main driving factor for using {\ttfamily \char`\"{}\char`\"{}} at all was that including a non-\/installed private header with {\ttfamily $<$$>$} would be unexpected, since non-\/installed headers shouldn\textquotesingle{}t be in the (standard) include-\/path. This distinction also makes it easier to ensure that non-\/installed headers are not accidentally included in installed ones.

See also considered alternatives.\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2077}{}\doxysection{Implications}\label{doc_decisions_4_decided_header_include_md_autotoc_md2077}

\begin{DoxyItemize}
\item All installed headers (and only those) must be put into {\ttfamily src/include/elektra}.
\item To enforce the restrictions on the path in an {\ttfamily \#include \char`\"{}\char`\"{}}, we will use a simple {\ttfamily grep}-\/based script that runs as a test case and as an early part of the CI (like e.\+g., the formatting check).
\item There must not be any {\ttfamily \#include $<$internal/...$>$}s anywhere within {\ttfamily src/include/elektra}. This will be enforced by the same {\ttfamily grep}-\/based script as the paths in {\ttfamily \#include \char`\"{}\char`\"{}}.
\end{DoxyItemize}\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2078}{}\doxysection{Related Decisions}\label{doc_decisions_4_decided_header_include_md_autotoc_md2078}

\begin{DoxyItemize}
\item \mbox{\hyperlink{doc_decisions_4_decided_header_file_structure_md}{Header File Structure}}
\item \mbox{\hyperlink{doc_decisions_4_decided_library_directory_structure_md}{Library Directory Structure}}
\end{DoxyItemize}\hypertarget{doc_decisions_4_decided_header_include_md_autotoc_md2079}{}\doxysection{Notes}\label{doc_decisions_4_decided_header_include_md_autotoc_md2079}
