|
Orrery
A GPU-accelerated N-body gravitational simulator
|
The definition of done requires that Orrery builds clean with Clang, GCC and MSVC with warnings as errors, and that address and undefined-behaviour sanitiser builds pass the full test suite. Both requirements are expressed as compiler flags, and both must apply to the code this project owns.
They must not apply to anything else. Catch2 is built from source inside the same CMake tree, and the later phases add more dependencies of the same kind. Third-party code compiled with this project's warning set will produce diagnostics, those diagnostics will be errors, and the project cannot fix them in code it does not own. The usual response is to start disabling warnings until the dependency compiles, which weakens the check for the code it was meant to protect.
No CMake code in this project assigns to CMAKE_CXX_FLAGS, calls add_compile_options at directory scope, or otherwise sets a flag globally. Build settings are carried on three interface libraries, defined in cmake/BuildSettings.cmake, and every target states which it wants:
clang-tidy follows the same rule. It is attached to individual targets through the CXX_CLANG_TIDY property in cmake/Linting.cmake, not set through CMAKE_CXX_CLANG_TIDY, which would lint every target created afterwards including the fetched dependencies.
Set CMAKE_CXX_FLAGS at the top of the tree. The shortest way to express the requirement and the reason the problem above exists. It also makes the project unusable as a subdirectory of anything else, since a consumer would silently acquire this project's flags.
add_compile_options in the project's own directories only. Better, and it does keep dependencies out of it, but the settings then follow directory structure rather than intent. A test executable and a benchmark in the same directory could not differ, and nothing in the build says which setting a target has or why.
One combined settings target. Simpler to write and simpler to forget to think about. Warnings and options differ in the property that matters here: warnings must stay private to this project and options must be public. Merging them forces one of the two to be wrong.
A toolchain file. Toolchain files describe the compiler and platform, not a project's opinion about diagnostics. Using one this way would make the project build differently depending on how it was configured, which is the opposite of what is wanted, and it would still apply to dependencies.
Every target the project defines has to link the interface libraries explicitly, and a target that forgets gets no warnings and no instrumentation. The failure is silent. With the small number of targets this project will have it is caught in review, but a helper function that wraps add_library becomes worth writing if the count grows.
Dependencies build with their own settings, which is the intended outcome: the project's warning set applies to the project, and Catch2's headers are marked as system headers so that their contents do not produce diagnostics in translation units that include them.
If Orrery is ever installed and exported for use through find_package, the interface targets that are linked publicly have to be exported alongside the libraries that use them. That is a known cost of the approach and is not addressed here, because the project does not install anything yet.