A set of re-usable and opinionated CMake and C++ utilities for Sourcemeta projects.
We recommend using vendorpull
to include Noa in your vendor
directory.
Like projects such as GoogleTest
, Noa follows the Abseil Live at Head philosophy. We recommend always following the latest commit in the main
branch.
To load the CMake utilities, include cmake/noa.cmake
as part of your project.
Noa will automatically set sane defaults for your project. You can check the list of applied defaults here. Note that these are only defaults. You can always override them after including Noa.
Instantiate a C++ executable with an opinionated target name and default options.
Calling this function will result in the following:
[<namespace>_]<project>_<name>
If OUTPUT
is declared, such variable will contain the target name created by this function.
Instantiate a C++ library with an opinionated structure and configuration.
If NAMESPACE
is declared, the files in PRIVATE_HEADERS
are resolved relatively to include/<namespace>/<name>/<name>_
. Otherwise, they are resolved relatively to include/<name>/<name>_
.
If NAMESPACE
is declared, the expected structure is as follows:
If NAMESPACE
is not declared, the expected structure is as follows:
If VARIANT
is declared, it allows for creating sub-libraries or variants of a main library. The expected structure changes as follows:
If NAMESPACE
is declared, calling this function will result in the following:
<namespace>_<project>_<name>
<namespace>::<project>::<name>
If NAMESPACE
is not declared, calling this function will result in the following:
<project>_<name>
<project>::<name>
In all cases:
<name>_export.h
, if the library is not header-onlyDeclare installation of opinionated Noa libraries created with noa_library
.
If NAMESPACE
is declared, calling this function will result in the following:
<namespace>_<project>_<name>
installation component<namespace>_<project>_<name>_dev
installation componentIf NAMESPACE
is not declared, calling this function will result in the following:
<project>_<name>
installation component<project>_<name>_dev
installation componentIn both cases:
LIBDIR/cmake/<project>
Setup ClangFormat using an opinionated configuration file based on the LLVM coding standards.
If the REQUIRED
option is set and ClangFormat is not found, configuration will abort.
After running this function, you will have two targets at your disposal:
clang_format
: Run the formatter on the files declared in the SOURCES
option and modify them in placeclang_format_test
: Run the formatter on the files declared in the SOURCES
option in dry-mode, reporting if there is any deviation. This option is meant to be used in a continuous-integration environmentFor example:
To run the targets:
Setup ClangTidy using an opinionated built-in configuration file.
If the REQUIRED
option is set and ClangTidy is not found, configuration will abort.
After running this function, you will have a new targets at your disposal:
clang_tidy
: Run the analyzer on the files declared in the SOURCES
optionFor example:
To run the targets:
Setup ShellCheck.
If the REQUIRED
option is set and ShellCheck is not found, configuration will abort.
After running this function, you will have a new targets at your disposal:
shellcheck
: Run the linter on the files declared in the SOURCES
optionFor example:
To run the targets:
Setup Doxygen with a templated configuration file.
On your configuration file, make sure to set OUTPUT_DIRECTORY
as follows:
After running this function, you will have a new target at your disposal:
doxygen
: Run Doxygen and store the output in the OUTPUT
directoryFor example:
To run the targets:
Configure a target with an opinionated set of strict compiler options. This function is used by default when making use of noa_library
.
For example:
cmake noa_add_vectorization_diagnostics([target])
cmake noa_add_vectorization_diagnostics(my_lib) ````
Provides a unified interface for setting up a set of compiler sanitizers project-wide.
Supported sanitizers and their respective compilers are as follows:
Sanitizer | Compiler | Description |
---|---|---|
address | LLVM | Clang AddressSanitizer |
memory | LLVM | Clang MemorySanitizer |
undefined | LLVM | Clang UndefinedBehaviorSanitizer |
For example:
Instantiate a C++ executable that links with GoogleTest.
Calling this function will result in the following:
[<namespace>_]<project>_<name>_unit
Instantiate a C++ executable that links with GoogleBenchmark.
Calling this function will result in the following:
[<namespace>_]<project>_benchmark
undefined
sanitizer on LLVM, run with LLDB along with the -fsanitize-trap=all
compiler option and set the UBSAN_OPTIONS=print_stacktrace=1
environment variableThe built-in file
command can be used to copy a file during the configure phase. Instead, this command copies a file at the build step to deal with generated files or as an optimization.
For example, you can declare a file to be copied at built-time, and then reference such output in a target for the copying to actually take place:
It is highly recommended to always copy files into the binary directory.
NOA_LANGUAGES
: A list of the programming languages declared in the last project
invocationNOA_COMPILER_LLVM
: Set to ON
if using the Clang or AppleClang compilersNOA_COMPILER_GCC
: Set to ON
if using the GNU GCC compilerNOA_COMPILER_MSVC
: Set to ON
if using the MSVC compilerFor example:
A shortcut for declaring CMake options that correspond to string enumerations.
This function will validate that user provided values (and your own default value) matches the provided choices. It will also make sure to provide a nice selection interface in cmake-gui(1)
.
For example:
CMake functionality shimmed to work on older versions: