libsgfc++ 2.0.1
A C++ library that uses SGFC to read and write SGF (Smart Game Format) data.
Loading...
Searching...
No Matches
Project notes

This file contains assorted project notes for which there is no better home.

Two project names: libsgfc++ and libsgfcplusplus

The official project name is libsgfc++. Please use the official name whenever possible, but at least in human-readable content.

The project's alternative name is libsgfcplusplus. Use the alternative name if the "+" characters in the official name might cause technical problems. For example GitHub does not allow "+" characters in a repository name.

libsgfc++ strives to be platform-independent. To minimize the risk of causing obscure technical issues on some platform the project uses "plusplus" instead of "++" in file names (e.g. source files, build artifacts).

The export header file

Basics

Symbol visibility when building the library and consuming the library is controlled by preprocessor magic hidden in the export header file SgfcPlusPlusExport.h. This file is conveniently generated by the CMake build system because it's a huge pain to write such a file correctly for many platforms and compilers.

All of the project's public header files that define symbols with visibility (e.g. classes) contain the following pattern:

// Project includes (generated)
#include "SgfcPlusPlusExport.h"
[...]
class SGFCPLUSPLUS_EXPORT SgfcFoo
[...]

Include directory

CMake generates the export header file in the out-of-source build tree. So how does the #include statement in the snippet above find the header file? The solution is that the CMake targets are configured with a special search path that points to the folder where the export header file was generated.

Example:

target_include_directories (
${SHARED_OBJECT_LIBRARY_TARGET_NAME}
PUBLIC
"$<BUILD_INTERFACE:${EXPORT_HEADER_FILE_FOLDER}>" <<< This is for the library build
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

Angle syntax vs. quotes syntax when including

When an included file is intended to be found via an include directory and not in a location relative to the including file, the #include statement should use the "angle bracket" syntax:

#include <SgfcPlusPlusExport.h>

As we have seen, however, the source code uses the "quotes" syntax:

#include "SgfcPlusPlusExport.h"

The reason is that when the library is built and installed the export header file is installed alongside with the other public header files. So in the final installation path the export header file loses its special designation as a generated file and becomes just another public API header file that resides in the same folder as its companions. In this context an #include statement using "quotes" syntax is the correct choice.

Using the "quotes" syntax is not just a matter of taste. Let's look at it from the side of a consumer of the library. Because the library installs its public headers in a subfolder libsgfcplusplus in the install prefix (e.g. /usr/local/include), a consumer is likely to write this statement to include one of the library's public header files:

#include <libsgfcplusplus/SgfcPlusPlusFactory.h>

This works fine because the compiler is bound to have an include directory pointing to the install prefix (/usr/local/include). Now if SgfcPlusPlusFactory.h were to use the "angle bracket" syntax to include the export header file, compilation would be extremely likely to fail, because the compiler has no include directory pointing to the libsgfcplusplus subfolder and therefore has no chance to find the export header file.

Going back to the point of view of building the library, compilation in that scenario is much more likely to succeed: The first attempt by the compiler to locate the export header file in the same folder as the including file fails. The compiler can then still fall back to look for the file in the specified include directories. The project relies on all supported platform's compilers to perform such a fall back search.