Skip to content

Commit

Permalink
doc: User guide (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
LecrisUT authored Dec 21, 2023
2 parents d71e4cc + 5566e4b commit 746b283
Show file tree
Hide file tree
Showing 16 changed files with 968 additions and 26 deletions.
20 changes: 18 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"breathe",
"sphinx.ext.intersphinx",
"sphinx_tippy",
"sphinx.ext.todo",
]

templates_path = []
Expand All @@ -29,20 +30,35 @@
"tasklist",
"colon_fence",
]
myst_heading_anchors = 3

intersphinx_mapping = {
"cmake": ("https://cmake.org/cmake/help/latest", None),
"sphinx": ("https://www.sphinx-doc.org/en/master", None),
"rtd": ("https://docs.readthedocs.io/en/stable", None),
"tmt": ("https://tmt.readthedocs.io/en/stable", None),
"sphinx-tippy": ("https://sphinx-tippy.readthedocs.io/en/latest", None),
"sphinx-hoverxref": ("https://sphinx-hoverxref.readthedocs.io/en/latest", None),
}

tippy_rtd_urls = [
## Only works with RTD hosted intersphinx
# Only works with RTD hosted intersphinx
# "https://cmake.org/cmake/help/latest",
# "https://www.sphinx-doc.org/en/master",
"https://www.sphinx-doc.org/en/master",
"https://docs.readthedocs.io/en/stable",
"https://tmt.readthedocs.io/en/stable",
"https://sphinx-tippy.readthedocs.io/en/latest",
"https://sphinx-hoverxref.readthedocs.io/en/latest",
]

copybutton_exclude = ".linenos, .gp, .go"

linkcheck_ignore = [
# pkgs.org gives 402 Client Error: Payment Required
r"https://pkgs.org",
]
linkcheck_anchors_ignore_for_url = [
r"https://gitlab.kitware.com/.*",
]

todo_include_todos = True
9 changes: 9 additions & 0 deletions docs/guides/developer.md → docs/guides/developer/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Developer guide

```{toctree}
: maxdepth: 2
: titlesonly: true
: hidden: true
: glob: true
who-is-the-developer
```

This is a developer's guide intended to explain many of the paradigms used in
this template project

Expand Down
11 changes: 11 additions & 0 deletions docs/guides/developer/who-is-the-developer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Who is the developer?

In the context of this guide, the developer is someone who:
- is looking to expand the build system to add more options, expand the project
dependencies
- a project developer who is looking at implementing this template project
- a CMake enthusiast looking for a common standard for their design. (Feel free
to interact in the template [issue page] if you have any comments)
- a non-CMake build-system enthusiast. There is no discrimination here :)

[issue page]: https://github.com/LecrisUT/CMake-Template/issues
88 changes: 81 additions & 7 deletions docs/guides/index.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,85 @@
# Guides

```{toctree}
---
maxdepth: 2
titlesonly: true
caption: Guides
glob: true
---
*
: maxdepth: 2
: titlesonly: true
user/index
developer/index
```

## What are these guides?

In this template project, you will find a [user guide] and a [developer guide]
intended to answer common questions that either a [user] or a [developer] would
have when encountering a project that uses this template.

Feel free to reference and/or [include] these guides or sections of it in your
documentation.

[user]: user/who-is-the-user.md
[developer]: developer/who-is-the-developer.md
[user guide]: user/index.md
[developer guide]: developer/index.md
[include]: #including-these-guides-in-your-downstream-project

## Including these guides in your downstream project

The best way to include these guides is if your project uses a
[sphinx backend][rtd-sphinx] for your documentation. There you can simply link
to it using [inter-sphinx]. For example, include the following configurations
to your `docs/conf.py` file:

```{code-block} python
: caption: docs/conf.py
: emphasize-lines: 5
extensions = [
"sphinx.ext.intersphinx",
]
intersphinx_mapping = {
"template-guide": ("https://lecrisut-cmake-template.readthedocs.io/en/latest/", None),
}
```

:::{note}
If you want to have the links pop-up like in this documentation, use either
[`sphinx-tippy`] or [`sphinx-hoverxref`]. The latter produces better results,
however it does [not yet support Markdown documents][sphinx-hoverxref-issue].
:::

Then, you can use it in your documentation files as follows:

::::{tab-set}
:::{tab-item} Markdown
```{code-block} markdown
: caption: docs/example.md
: emphasize-lines: 4
Refer to the [following guide][template-user-guide] for a basic how-to interact
with a CMake project...
[template-user-guide]: inv:template-user-guide:std:doc#guides/user/index
```
:::
:::{tab-item} reStructuredText
```{code-block} rst
: caption: docs/example.rst
: emphasize-lines: 1
Refer to the :external+template-user-guide:std:doc:`following guide<template-user-guide>`
for a basic how-to interact with a CMake project...
```
:::
:::{tab-item} (Result)
Refer to the [following guide][user guide] for a basic how-to interact with a
CMake project...
:::
::::

[rtd-sphinx]: inv:rtd:std:doc#intro/getting-started-with-sphinx
[//]: # (TODO: Fix the intersphinx link)
[inter-sphinx]: https://www.sphinx-doc.org/en/master/usage/quickstart.html#intersphinx
[`sphinx-tippy`]: inv:sphinx-tippy#index
[`sphinx-hoverxref`]: inv:sphinx-hoverxref#index
[sphinx-hoverxref-issue]: https://github.com/readthedocs/sphinx-hoverxref/issues/250
6 changes: 0 additions & 6 deletions docs/guides/user.md

This file was deleted.

39 changes: 39 additions & 0 deletions docs/guides/user/build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Building the project

:::{admonition} Tl;dr
```console
$ cmake --build ./build-dir
```
:::

At this point the build process is more-or-less up to the actual project, and
you simply run the build as shown above. Here are also a few tips:

## Using presets

If you have used a [`configurePreset`] in the previous section, you may not be
aware of the build directory. Often times, the project also provides a
`buildPreset` with the same name, so you can simply run:
```console
$ cmake --build --preset default
```

You can find a list of them using:
```console
$ cmake --list-preset=build
```

## Running in parallel

Use the [`-j`] option, either by itself (the build system decides) or pass
`$(nproc)` as its value.

```console
$ cmake --build ./build-dir -j
```

Alternatively, set the [`CMAKE_BUILD_PARALLEL_LEVEL`] environment variable.

[`-j`]: inv:cmake:std:cmdoption#cmake--build.--parallel
[`configurePreset`]: configure/index.md#cmake-presets
[`CMAKE_BUILD_PARALLEL_LEVEL`]: inv:cmake:cmake:envvar#envvar:CMAKE_BUILD_PARALLEL_LEVEL
129 changes: 129 additions & 0 deletions docs/guides/user/configure/import.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Importing dependencies

This section covers both how to import a project in another CMake project
([importing]), and how a user can control where a project is found ([finding]).

## Importing dependencies in a CMake project

:::{admonition} Tl;dr
```cmake
include(FetchContent)
FetchContent_Declare(awesome-project
GIT_REPOSITORY https://github.com/user/awesome-project
GIT_TAG main
FIND_PACKAGE_ARGS CONFIG
)
FetchContent_MakeAvailable(awesome-project)
```
:::

The best way to consume a project is within CMake, using the
[`FetchContent`/`find_package` integration]. This will run [`find_package`]
first to try and import the system installed [packaged] version, and if none is
available it will git clone the [source] project and include it as
[`add_subdirectory`]. See the [configuration] section on how to configure the
included project.

From there, navigate the dependency's top-level `CMakeLists.txt` to find the
available targets you can use.

If you need to overwrite the upstream project's options, simply add the
[`option`] before the [`FetchContent_MakeAvailable`] call, e.g.:
```cmake
option(PROJECT2_TESTS "Project1: Override" OFF)
FetchContent_MakeAvailable(Project2)
```

### Making a dependency optional

Currently, the only clear design for supporting optional dependencies is by
avoiding [`FetchContent`] and using [`find_package`] only:

```cmake
find_package(awesome-project)
```

See the [controlling] section on how to disable or make it a required
dependency.

:::{todo}
Make the optional dependency work with [`FetchContent`]. Currently, there is no
clear way how to combine [`find_package`] and [`FetchContent`] fallthrough.
Key part is the interaction with [`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`]
and [`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`].
:::

## How dependencies are found

Here we assume that all projects in the chain use the modern [importing]
approach to define their dependencies.

### Default behavior

By default, the project will first try to find the [`<PackageName>Config.cmake`]
file from the system installed [packaged], and if that fails, it would either
use [`FetchContent`] to download the [source] project if it is a required
dependency, or simply disable the feature if it is an [optional dependency].

### Controlling how dependencies are imported

| Option | Effect | Notes |
|:--------------------------------------------:|:-------------------------------------------------------|:-------------------------------------------------------------------------------------------|
| [`CMAKE_PREFIX_PATH`] | Where to look for system installed package | |
| [`<PackageName>_ROOT`] | Where to look for system installed package | It can happen that this is not enforced |
| [`FETCHCONTENT_TRY_FIND_PACKAGE_MODE`] | If `NEVER`, will use downloaded version | |
| [`FETCHCONTENT_SOURCE_DIR_<PACKAGENAME>`] | Path to package source to use (instead of downloading) | Takes precedence of any other option |
| [`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`] | Make optional dependency required | If dependency is already required via `FetchContent`, it ensure the system package is used |
| [`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`] | Disable finding system installed package | |

Here `<PackageName>` is the case-sensitive name of the dependency, and
`<PACKAGENAME>` is the equivalent uppercase name.

:::{caution}
[`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`] and
[`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`] options propagate to other
dependencies in the chain. Normally this would not be an issue, unless a project
uses [`Find<PackageName>.cmake`] and do not take this into account [^1].
:::

### Troubleshooting the dependency search

:::{admonition} Tl;dr
```console
$ cmake -b ./build --debug-find-pkg=<PackageName>
```
:::

The most comprehensive way of finding out how a dependency has been searched is
to use the [`--debug-find-pkg`] option. This does not cover the
[`Find<PackageName>.cmake`], where the find process is non-standard.

[importing]: #importing-dependencies-in-a-cmake-project
[finding]: #how-dependencies-are-found
[controlling]: #controlling-how-dependencies-are-imported
[optional dependency]: #making-a-dependency-optional

[packaged]: ../download.md#packaged-version
[source]: ../download.md#source-project
[configuration]: options.md#upstream-project-options

[`FetchContent`]: inv:cmake:cmake:module#module:FetchContent
[`find_package`]: inv:cmake:cmake:command#command:find_package
[`FetchContent`/`find_package` integration]: inv:cmake:std:label#fetchcontent-find_package-integration-examples
[`add_subdirectory`]: inv:cmake:cmake:command#command:add_subdirectory

[`CMAKE_PREFIX_PATH`]: inv:cmake:cmake:variable#variable:CMAKE_PREFIX_PATH
[`<PackageName>_ROOT`]: inv:cmake:cmake:variable#variable:<PackageName>_ROOT
[`FETCHCONTENT_TRY_FIND_PACKAGE_MODE`]: inv:cmake:cmake:variable#variable:FETCHCONTENT_TRY_FIND_PACKAGE_MODE
[`FETCHCONTENT_SOURCE_DIR_<PACKAGENAME>`]: inv:cmake:cmake:variable#variable:FETCHCONTENT_SOURCE_DIR_<uppercaseName>
[`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`]: inv:cmake:cmake:variable#variable:CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
[`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`]: inv:cmake:cmake:variable#variable:CMAKE_DISABLE_FIND_PACKAGE_<PackageName>

[`FetchContent_MakeAvailable`]: inv:cmake:cmake:command#command:fetchcontent_makeavailable
[`option`]: inv:cmake:cmake:command#command:option
[`<PackageName>Config.cmake`]: <inv:cmake:std:label#full signature>
[`Find<PackageName>.cmake`]: <inv:cmake:std:label#find modules>
[`--debug-find-pkg`]: inv:cmake:std:cmdoption#cmake.--debug-find-pkg

[^1]: <https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8951#note_1442376>
Loading

0 comments on commit 746b283

Please sign in to comment.