Skip to content

Commit e2722d2

Browse files
committed
Initial draft of new documentation
1 parent 2627864 commit e2722d2

File tree

7 files changed

+179
-18
lines changed

7 files changed

+179
-18
lines changed

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,29 @@ type = "executable"
1313
sources = ["src/main.cpp"]
1414
```
1515

16-
`cmkr` can bootstrap itself from CMake and you only need CMake to use it.
16+
`cmkr` can bootstrap itself and you only need CMake and a C++ compiler to use it.
1717

1818
## Getting started
1919

20-
To get started run the following commands from your project directory:
20+
To get started, run the following commands from your project directory:
2121

2222
```sh
2323
curl https://raw.githubusercontent.com/build-cpp/cmkr/main/cmake/cmkr.cmake -o cmkr.cmake
2424
cmake -P cmkr.cmake
2525
```
2626

27-
After the bootstrapping process finishes, modify [`cmake.toml`](https://build-cpp.github.io/cmkr/cmake-toml) and open the project in your favorite IDE or build with CMake:
27+
After the bootstrapping process finishes, customize [`cmake.toml`](https://build-cpp.github.io/cmkr/cmake-toml) for your project and run CMake:
2828

2929
```sh
3030
cmake -B build
3131
cmake --build build
3232
```
3333

34-
Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt`.
34+
Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt` when necessary.
3535

36-
In CI settings the `cmkr` bootstrapping process is skipped so there is no extra configure-time overhead in your pipelines.
36+
<sub>**Note**: The `cmake.toml` project file, generated `CMakeLists.txt` and `cmkr.cmake` bootstrapping script are all intended to be added to source control.</sub>
37+
38+
In CI environments the `cmkr` bootstrapping process is skipped, so there is no additional overhead in your pipelines.
3739

3840
## Template repositories
3941

@@ -53,10 +55,10 @@ Optionally you can put a [`cmkr` release](https://github.com/build-cpp/cmkr/rele
5355
```
5456
Usage: cmkr [arguments]
5557
arguments:
56-
init [executable|library|shared|static|interface] Starts a new project in the same directory.
58+
init [executable|library|shared|static|interface] Create a project.
5759
gen Generates CMakeLists.txt file.
5860
build <extra cmake args> Run cmake and build.
59-
install Run cmake --install. Needs admin privileges.
61+
install Run cmake --install.
6062
clean Clean the build directory.
6163
help Show help.
6264
version Current cmkr version.

docs/concepts.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
layout: page
3+
# TODO: rename to 'Basics'?
4+
title: Concepts
5+
nav_order: 2
6+
---
7+
8+
# Concepts (TODO: rename to "Basics" or "Basic Concepts"?)
9+
10+
To effectively use cmkr it helps to understand the basic concepts of CMake.
11+
12+
## Projects
13+
14+
A CMake **project** is a collection of targets. In the context of libraries the project usually corresponds to the **package** that other projects can depend on.
15+
16+
<sub>Visual Studio: a CMake **project** corresponds to a _solution_.</sub>
17+
18+
## Targets
19+
20+
The basic unit of CMake is called a **target**. A target (also referred to as [binary target](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#binary-targets) in the CMake documentation) corresponds to an executable or library you can build. There are also [pseudo targets](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#pseudo-targets), but we ignore them for now.
21+
22+
<sub>Visual Studio: a **target** corresponds to a _project_.</sub>
23+
24+
## Target Properties
25+
26+
Targets have a collection of **properties** that describe how to build them.
27+
28+
Examples of properties:
29+
30+
- _Sources_: the `*.cpp` files used to build the target.
31+
- _Compile options_: Command line flags for the compiler.
32+
- _Link libraries_: The **dependencies** required to build this target.
33+
34+
<sub>See the [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets) for an exhaustive list of target properties.</sub>
35+
36+
**Important**: The term **link** has a slightly different meaning in CMake than you might expect. In addition to adding a library to the command line of the linker, CMake also propagates properties of the target you link to.
37+
38+
<sub>You can think of **linking** as _depending on_.</sub>
39+
40+
The propagation of properties depends on their **visibility**:
41+
42+
- **Private**: properties that are only used when building the target itself.
43+
- **Interface**: properties that are used when depending on this target.
44+
- **Public**: combination of private and interface.
45+
46+
In practice you default to **private**, unless consumers of your library _require_ the property to build their target. In that case you use **public**.
47+
48+
### Example
49+
50+
The most intuitive example is with _include directories_. Imagine there are two targets:
51+
52+
1. `StringUtils`: A library with string utilities.
53+
- _Sources_: `StringUtils/src/stringutils.cpp`
54+
- _Include directories_: `StringUtils/include`
55+
2. `DataProcessor`: An executable that uses functionality from `StringUtils` to process some data.
56+
- _Sources_: `DataProcessor/src/main.cpp`
57+
- _Link libraries_: `StringUtils`
58+
59+
The _include directories_ property of `StringUtils` has to be **public**. If it was **private**, the `DataProcessor` target would fail to `#include <stringutils.hpp>` since the _include directories_ property is not propagated.
60+
61+
The `cmake.toml` for this example would look something like this:
62+
63+
```toml
64+
[project]
65+
name = "DataProcessor"
66+
67+
[target.StringUtils]
68+
type = "static"
69+
sources = ["StringUtils/src/stringutils.cpp"]
70+
headers = ["StringUtils/include/stringutils.hpp"]
71+
include-directories = ["StringUtils/include"]
72+
73+
[target.DataProcessor]
74+
type = "executable"
75+
sources = ["DataProcessor/src/main.cpp"]
76+
link-libraries = ["StringUtils"]
77+
```

docs/index.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ nav_order: 0
66

77
# Index
88

9-
`cmkr`, pronounced "cmaker", is a modern build system based on [CMake](https://cmake.org/) and [TOML](https://toml.io).
9+
[`cmkr`](https://github.com/build-cpp/cmkr), pronounced "cmaker", is a modern build system based on [CMake](https://cmake.org/) and [TOML](https://toml.io).
1010

1111
`cmkr` parses `cmake.toml` files and generates a modern, idiomatic `CMakeLists.txt` for you. A minimal example:
1212

@@ -19,27 +19,29 @@ type = "executable"
1919
sources = ["src/main.cpp"]
2020
```
2121

22-
`cmkr` can bootstrap itself from CMake and you only need CMake to use it.
22+
`cmkr` can bootstrap itself, and you only need CMake and a C++ compiler to use it.
2323

2424
## Getting started
2525

26-
To get started run the following commands from your project directory:
26+
To get started, run the following commands from your project directory:
2727

2828
```sh
2929
curl https://raw.githubusercontent.com/build-cpp/cmkr/main/cmake/cmkr.cmake -o cmkr.cmake
3030
cmake -P cmkr.cmake
3131
```
3232

33-
After the bootstrapping process finishes, modify [`cmake.toml`](https://build-cpp.github.io/cmkr/cmake-toml) and open the project in your favorite IDE or build with CMake:
33+
After the bootstrapping process finishes, customize [`cmake.toml`](./cmake-toml) for your project and run CMake:
3434

3535
```sh
3636
cmake -B build
3737
cmake --build build
3838
```
3939

40-
Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt`.
40+
Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt` when necessary.
4141

42-
In CI settings the `cmkr` bootstrapping process is skipped so there is no extra configure-time overhead in your pipelines.
42+
<sub>**Note**: The `cmake.toml` project file, generated `CMakeLists.txt` and `cmkr.cmake` bootstrapping script are all intended to be added to source control.</sub>
43+
44+
In CI environments the `cmkr` bootstrapping process is skipped, so there is no additional overhead in your pipelines.
4345

4446
## Template repositories
4547

@@ -59,10 +61,10 @@ Optionally you can put a [`cmkr` release](https://github.com/build-cpp/cmkr/rele
5961
```
6062
Usage: cmkr [arguments]
6163
arguments:
62-
init [executable|library|shared|static|interface] Starts a new project in the same directory.
64+
init [executable|library|shared|static|interface] Create a project.
6365
gen Generates CMakeLists.txt file.
6466
build <extra cmake args> Run cmake and build.
65-
install Run cmake --install. Needs admin privileges.
67+
install Run cmake --install.
6668
clean Clean the build directory.
6769
help Show help.
6870
version Current cmkr version.

docs/philosophy.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
layout: page
3+
title: Philosophy
4+
nav_order: 3
5+
---
6+
7+
# Philosophy
8+
9+
## Problem statement
10+
11+
Similar to writing good C++, writing good CMake is difficult. The main difference is that nobody actually wants to learn CMake. The build system is something that should "just work".
12+
13+
There have been many attempts at creating new build systems (with varying levels of success). Naturally this causes [competing standards](https://xkcd.com/927/), which is undesirable. CMake is pretty much the de facto standard, and it has seen extensive use in complex software projects.
14+
15+
One of the main issues of CMake is the turing-complete scripting language you use to describe your projects. As your project gets more complex this can be very helpful, but it also unnecessarily complicates simple projects. There have been discussions about a declarative language on the [CMake issue tracker](https://gitlab.kitware.com/cmake/cmake/-/issues/19891) to solve this problem, but it looks like a "LISP-like" language is seriously being considered...
16+
17+
## The solution
18+
19+
The way cmkr (pronounced "cmaker") solves this problem is by using [TOML](https://toml.io/). Below is a minimal `cmake.toml` project:
20+
21+
```toml
22+
[project]
23+
name = "cmkr_for_beginners"
24+
25+
[target.hello_world]
26+
type = "executable"
27+
sources = ["src/main.cpp"]
28+
```
29+
30+
The key difference between `cmkr` and other build systems is that it _generates_ CMake. This means that your projects are fully compatible with the CMake ecosystem, and you can try it out without having to rewrite your whole build system.
31+
32+
TODO: link/include more examples? Talk about conditions, packaging (missing)
33+
34+
### Another layer?!
35+
36+
A common issue people have with cmkr is that it introduces an additional layer of indirection to your build system. CMake is already a meta-buildsystem, which means you could call cmkr a "meta-meta-buildsystem".
37+
38+
Presumably the reason for this friction is that additional layers of abstraction introduce additional complexity. Because of this cmkr has been designed to be completely seamless:
39+
40+
- The user doesn't have to install any additional software to use cmkr. All you need is a semi-recent version of CMake and a C++ compiler.
41+
- Modifying `cmake.toml` automatically triggers a regeneration of `CMakeLists.txt`. There is no change to your build process.
42+
- The `CMakeLists.txt` is generated to be human-readable. This means you can easily "eject" from cmkr and go back to CMake.
43+
44+
An additional argument for cmkr is that anecdotally people say it "just works". Because of its simplicity it's also easy to teach, even to people without programming experience.
45+
46+
There is also precedent in the JavaScript community. Bundlers and translators are the norm there and their developer experience is miles ahead of C++.
47+
48+
<sub>Not to say the JavaScript ecosystem is without its flaws, but generators does not appear to be one of them</sub>
49+
50+
### Unsupported features
51+
52+
Because cmkr is still in early in development there are many missing/unfinished features. It was decided that users can bridge the gap by including CMake at arbitrary locations.
53+
54+
This has the advantage that it forces complexity in the build system to be self-contained and modular, a problem all too common in projects as they age.
55+
56+
## Enterprise
57+
58+
Words like "bootstrapping" and "generating code" might worry engineers working in an enterprise environment, and rightly so. From the beginning it has been a priority to make cmkr suitable for use in big corporations with strict protocols for security and reproducibility.
59+
60+
### No additional dependencies
61+
62+
As mentioned above, the only thing you need is a working C++ compiler and a semi-recent version of CMake. It is assumed that you are already building (and executing) C++ projects on your servers, so cmkr does not introduce additional requirements.
63+
64+
All the logic for downloading and compiling the `cmkr` executable is self-contained in a ~250 line `cmkr.cmake` script. You can easily audit it and see if it's up to your standards.
65+
66+
### Reproducibility
67+
68+
Per default the `cmkr.cmake` bootstrapping script contains the exact version of cmkr used to generate your project. As long as the cmkr repository is available you will build the exact same version of cmkr, which will generate the exact same `CMakeLists.txt` file.
69+
70+
This also means that cmkr can decide to break backwards compatibility without affecting legacy projects. An effort will always be made to maintain backwards compatibility though.
71+
72+
### Integrity
73+
74+
As an additional safeguard you can modify `cmkr.cmake` to pin the version tag to a commit hash. This hash is checked to ensure the integrity of the upstream repository.
75+
76+
### Availability
77+
78+
You can easily point `cmkr.cmake` to a mirror of the cmkr repository to ensure availability should something catastrophic happen.
79+
80+
### Not executed in CI
81+
82+
The final (and key) feature is that the bootstrapping process is never executed in CI environments. This means `cmkr` is only ever executed on your developer's machines and not on your infrastructure.

docs/placeholder.txt

Whitespace-only changes.

docs/run-locally.sh

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
bundle install
2-
bundle exec jekyll serve --force_polling --livereload --incremental
2+
bundle exec jekyll serve --force_polling --livereload --incremental

0 commit comments

Comments
 (0)