README.md
ca1706cf
 # [`cmake-common`][]
 
 A [CMake][]\>=3.14 [C++][] common project helper.
 
07bf119f
 [CMake][] has many useful features but requires verbose per-project
 configuration to enable them. This helper allows you to just place your files
 where everyone expects them to be anyway, install the tools you want to use,
 and things like downloading dependencies, linting, building, testing,
 sanitizing, packaging (build artifacts, assets, documentation), and installing
 will automatically be enabled.
 
ca1706cf
 [`cmake-common`]: https://git.rcrnstn.net/rcrnstn/cmake-common
 [CMake]: https://cmake.org
 [C++]: https://en.wikipedia.org/wiki/C++
0f1a1c8c
 
 ## Usage
 
 This work is licensed in such a way that you may use it however you please,
 including relicensing, without attribution. As such, the encouraged way to use
 this work is to simply copy the required files or content into your project,
 optionally(!) mentioning where it came from in the readme or other
 documentation. See [License][].
 
07bf119f
 Copy the file [`common.cmake`][] into your project and [`include`][] it from
 (e.g.) the main [`CMakeLists.txt`][]. This will define a `common` function that
 takes a number of arguments to configure the project.
 
0f1a1c8c
 [License]: #license
07bf119f
 [`include`]: https://cmake.org/cmake/help/v3.14/command/include.html
 [`common.cmake`]: common.cmake
 [`CMakeLists.txt`]: https://cmake.org/cmake/help/v3.14/manual/cmake-language.7.html#directories
 
 ### Overview
 
 ```cmake
 ## CMake
 cmake_minimum_required(VERSION 3.14)
 if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE Debug)
 endif()
 
 ## Project
 project(project-name
     VERSION 1.0.0
     LANGUAGES CXX
 )
 
 ## Main target
 add_library(${PROJECT_NAME})
 
 ## Common
 include(common.cmake)
 common(
     CXX_STANDARD 11
     DISABLE_INCLUDE_WHAT_YOU_USE
     PACKAGES
         Package
     EXTERNAL
         external_project
     FETCHCONTENT
         "https://example.com/user/online_project GIT_TAG v1.2.3"
     DEPENDENCIES_PUBLIC
         Package::Package
     DEPENDENCIES_PRIVATE
         external_project
     DEPENDENCIES_TESTS
         online_project
     DEFINITIONS
         PROJECT_FEATURE
 )
 ```
 
 ### Main target
 
 If there are files in the `src` and/or `include` directories, they are added as
 sources to a single "main" target, which is assumed to already be declared with
 the name `${`[`PROJECT_NAME`][]`}` (which is automatically set by CMake when
 calling [`project`][]). The "main" target may be of any type, such as [normal
 executable][], [normal library][], [interface library][], or [custom target][]
 (the latter probably with the `ALL` specifier, so that it is added to the
 default build target so that it will be run every time).
 
 [`PUBLIC`][] dependencies are taken from `DEPENDENCIES_PUBLIC` and
 [`PRIVATE`][] dependencies are taken from `DEPENDENCIES_PRIVATE`, see
 [Dependencies][].
 
 For [top level project][]s, `*Config.cmake` and `*ConfigVersion.cmake` files
 that can be used by [`find_package`][] to find this project are
 [`install`][]ed, see [Packaging][].
 
 [`PROJECT_NAME`]: https://cmake.org/cmake/help/v3.14/variable/PROJECT_NAME.html
 [`project`]: https://cmake.org/cmake/help/v3.14/command/project.html
 [normal executable]: https://cmake.org/cmake/help/v3.14/command/add_executable.html#normal-executables
 [normal library]: https://cmake.org/cmake/help/v3.14/command/add_library.html#normal-libraries
 [interface library]: https://cmake.org/cmake/help/v3.14/command/add_library.html#interface-libraries
 [custom target]: https://cmake.org/cmake/help/v3.14/command/add_custom_target.html
 [`PUBLIC`]: https://cmake.org/cmake/help/v3.14/manual/cmake-buildsystem.7.html#target-usage-requirements
 [`PRIVATE`]: https://cmake.org/cmake/help/v3.14/manual/cmake-buildsystem.7.html#target-usage-requirements
 [Dependencies]: #dependencies
 [top level project]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_PROJECT_NAME.html
 [`find_package`]: https://cmake.org/cmake/help/v3.14/command/find_package.html
 [`install`]: https://cmake.org/cmake/help/v3.14/command/install.html
 [Packaging]: #packaging
 
 ### Test targets
 
 For [top level project][]s, every file directly under the `tests` directory is
 individually added as a source to a separate executable "test" target, which is
 automatically declared with the name `${PROJECT_NAME}-test-${TEST_NAME}` and
 passed to [`add_test`][]. All files in the `tests/common` directory are also
 added as sources to all "test" targets.
 
 A ([`PRIVATE`][]) dependency on the "main" target is declared and further
 ([`PRIVATE`][]) dependencies are taken from `DEPENDENCIES_TESTS`, see
 [Dependencies][].
 
 CMake can be run with the standard `-D`[`BUILD_TESTING`][]`=OFF` to disable
 testing.
 
 See [Testing][].
 
 [`add_test`]: https://cmake.org/cmake/help/v3.14/command/add_test.html
 [`BUILD_TESTING`]: https://cmake.org/cmake/help/v3.14/module/CTest.html
 [Testing]: #testing
 
 ### Assets
 
 If there are files in the `assets` directory, a target named
 `${PROJECT_NAME}-assets` that runs by default and [symlink][]s them to
 `${`[`CMAKE_BINARY_DIR`][]`}/assets` is automatically declared.
 
 If the path does not include `/tests/`, the asset is [`install`][]ed into
 `${`[`CMAKE_INSTALL_DATADIR`][]`}/${CMAKE_PROJECT_NAME}/assets` (note that
 `CMAKE_PROJECT_NAME` is the name of the [top level project][]), see
 [Packaging][].
 
 [symlink]: https://en.wikipedia.org/wiki/Symbolic_link
 [`CMAKE_BINARY_DIR`]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_BINARY_DIR.html
 [`CMAKE_INSTALL_DATADIR`]: https://cmake.org/cmake/help/v3.14/module/GNUInstallDirs.html
 
 ### Documentation
 
 For [top level project][]s, documentation from the `doc` directory and
 repository root is automatically [`install`][]ed, see [Packaging][].
 
 ### Man pages
 
 For [top level project][]s, [man page][]s from the `man` directory is
 automatically [`install`][]ed, see [Packaging][].
 
 [man page]: https://en.wikipedia.org/wiki/Man_page
 
 ### Dependencies
 
 Dependencies on other targets are declared with `DEPENDENCIES_PUBLIC`,
 `DEPENDENCIES_PRIVATE`, and `DEPENDENCIES_TESTS`, see [Main target][] and [Test
 targets][].
 
 Three mechanisms to make these dependencies available are provided, given as
 arguments to the `common` function:
 
 -   `PACKAGES`: Packages passed to [`find_package`][]`(...)` in order to find
     system packages.
 -   `EXTERNAL`: Subdirectories of `external` that is passed to
     [`add_subdirectory`][].
 -   `FETCHCONTENT`: [Git][] [URL][]s passed to [`FetchContent_Declare`][]'s
     `GIT_REPOSITORY`. If a specific [Git tag][] is wanted, specify it in the
     same (quoted) argument, delimited with `GIT_TAG`, see [Usage][].
     (`GIT_SHALLOW` and `GIT_PROGRESS` are always set to `TRUE`).
     [`FetchContent_MakeAvailable`][] is automatically called in order to
     download and make targets available during the CMake configure step.
 
 If more involved steps are required to make targets available, perform them
 manually before calling the `common` function.
 
 [Main target]: #main-target
 [Test targets]: #test-targets
 [`add_subdirectory`]: https://cmake.org/cmake/help/v3.14/command/add_subdirectory.html
 [Git]: https://git-scm.com
 [URL]: https://en.wikipedia.org/wiki/URL
 [`FetchContent_Declare`]: https://cmake.org/cmake/help/v3.14/module/FetchContent.html#command:fetchcontent_declare
 [`FetchContent_MakeAvailable`]: https://cmake.org/cmake/help/v3.14/module/FetchContent.html#command:fetchcontent_makeavailable
 [Git tag]: https://git-scm.com/book/en/v2/Git-Basics-Tagging
 [Usage]: #usage
 
 ### Preprocessor definitions
 
 [Preprocessor definitions][] can be specified with the `DEFINITIONS` argument
 to the `common` function. Both `NAME` and `NAME=EXPANSION` forms are supported.
 
 [preprocessor definitions]: https://en.cppreference.com/w/cpp/preprocessor/replace#.23define_directives
 
 ### Language version
 
 For [top level project][]s, the `CXX_STANDARD` argument to the `common`
 function sets the [`CXX_STANDARD`][] property applied to configured targets
 ([`CXX_STANDARD_REQUIRED`][] is always set to `ON`, [`CXX_EXTENSIONS`][] is
 always set to `OFF`).
 
 [`CXX_STANDARD`]: https://cmake.org/cmake/help/v3.14/prop_tgt/CXX_STANDARD.html
 [`CXX_STANDARD_REQUIRED`]: https://cmake.org/cmake/help/v3.14/prop_tgt/CXX_STANDARD_REQUIRED.html
 [`CXX_EXTENSIONS`]: https://cmake.org/cmake/help/v3.14/prop_tgt/CXX_EXTENSIONS.html
 
 ### Build options
 
 For [top level project][]s, aggressive warnings are enabled and treated as
 errors.
 
 For projects compiled with [GCC][] or [Clang][], [`-Wshadow`][] is enabled by
 default, but can be disabled by passing `DISABLE_WSHADOW` to the `common`
 function.
 
 For projects compiled with [MSVC][], [`/Zc:__cplusplus`][] is enabled.
 
 If supported, [interprocedural optimization][] (also known as link-time
 optimization) is enabled.
 
 For projects compiled with the `Debug` [build type][] with [GCC][] or
 [Clang][], [address sanitizer][] ([wiki][address sanitizer wiki]), [leak
 sanitizer][] ([wiki][leak sanitizer wiki]), and [undefined behavior
 sanitizer][] are linked into all targets. The sanitizers can be disabled by
 passing `DISABLE_SANITIZERS` to the `common` function. Suppression files that
 match the [glob][]s `*.asan.supp`, `*.lsan.supp`, and `*.ubsan.supp`
 respectively in the repository root are automatically used.
 
 [GCC]: https://gcc.gnu.org
 [Clang]: https://clang.llvm.org
 [`-Wshadow=`]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wshadow
 [MSVC]: https://visualstudio.microsoft.com/vs/
 [`/Zc:__cplusplus`]: https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus
 [interprocedural optimization]: https://en.wikipedia.org/wiki/Interprocedural_optimization
 [build type]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_BUILD_TYPE.html
 [address sanitizer]: https://clang.llvm.org/docs/AddressSanitizer.html
 [address sanitizer wiki]: https://github.com/google/sanitizers/wiki/AddressSanitizer
 [leak sanitizer]: https://clang.llvm.org/docs/LeakSanitizer.html
 [leak sanitizer wiki]: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer
 [undefined behavior sanitizer]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
 [glob]: https://en.wikipedia.org/wiki/Glob_(programming)
 
 ### Tools
 
 For [top level project][]s compiled with the `Debug` [build type][],
 [Cppcheck][], [Clang-Tidy][], and [Include What You Use][] are automatically
 configured if present on the system. The tools can be disabled by passing the
 `DISABLE_CPPCHECK`, `DISABLE_CLANG_TIDY`, and/or `DISABLE_INCLUDE_WHAT_YOU_USE`
 options, respectively, to the `common` function. CppCheck suppressions list
 files that match the [glob][] `.cppcheck.supp`, a Clang-Tidy configuration file
 named `.clang-tidy`, and Include What You Use [mapping files][] that match the
 [glob][] `*.iwyu.imp`, in the repository root, are automatically used.
 
 [Cppcheck]: https://cppcheck.sourceforge.io
 [Clang-Tidy]: https://clang.llvm.org/extra/clang-tidy
 [Include What You Use]: https://include-what-you-use.org
 [mapping files]: https://github.com/include-what-you-use/include-what-you-use/blob/0.20/docs/IWYUMappings.md
 
 ### Testing
 
 For [top level project][]s, [CTest][] is automatically configured and can be
 run with [`ctest`][], see the [`BUILDING.md`][] auxiliary file.
 
 [CTest]: https://cmake.org/cmake/help/v3.14/module/CTest.html
 [`ctest`]: https://cmake.org/cmake/help/v3.14/manual/ctest.1.html
 [`BUILDING.md`]: BUILDING.md
 
 ### Packaging
 
 For [top level project][]s, [CPack][] is automatically configured and can be
 run with [`cpack`][], see the [`BUILDING.md`][] auxiliary file.
 
 [CPack]: https://cmake.org/cmake/help/v3.14/module/Pack.html
 [`cpack`]: ttps://cmake.org/cmake/help/v3.14/manual/cpack.1.html
 
 ## Auxiliary files
 
 This repository includes some files besides [`common.cmake`][] that may be of
 use:
 
 -   [`BUILDING.md`][]: Instructions to build a project that uses
     [`cmake-common`][].
 
 -   [`.gitignore`][]: A configuration file for [Git][] that makes it ignore the
     created `_build` directory created when following the instructions in
     [`BUILDING.md`][].
 
 -   [`.cppcheck.supp`][]: A suppressions list for [CppCheck][] with a set of
     suppressed warnings.
 
 -   [`.clang-tidy`][]: A configuration file for [Clang-Tidy][] with a set of
     enabled and disabled warnings.
 
 [`.gitignore`]: .gitignore
 [`.cppcheck.supp`]: .cppcheck.supp
 [`.clang-tidy`]: .clang-tidy
0f1a1c8c
 
 ## License
 
 Licensed under the [BSD 0-Clause License][] unless otherwise noted, see the
07bf119f
 [`LICENSE`][] file.
0f1a1c8c
 
 [BSD 0-Clause License]: https://choosealicense.com/licenses/0bsd/
07bf119f
 [`LICENSE`]: LICENSE