Skip to content

Commit

Permalink
Refresh installation instructions (#302)
Browse files Browse the repository at this point in the history
The old flow of the page dates from the first open source release, when
only bazel was fully supported, and we provided the single-file
packaging as the "lowest common denominator" fallback that worked with
everybody.  This summer, we added official CMake support, and just last
week, the community also added support for both conan and vcpkg.  This
radically changes and simplifies the recommended installation approach:
now "full install" is the right choice for almost everyone! Accordingly,
it's time to refresh our instructions.

- Make up-front guidance simpler and more direct
- Rearrange the table: put Full Install first; unify Full Install
  columns; clean up and explain some text
- Remove decision flowchart: things are much simpler now, and we don't
  really need it
- Refresh the bazel instructions to mention 0.3.5 (might as well)
- Add links and instructions for installing with package managers
- Move the single-file section _after_ the full install one

I used "checkpoint commits" for this PR, so this last change is in a
separate "pure-move" commit within the PR, to make this easier to
review.

The reviewer can also run `au-docs-serve` and do A/B comparison between
two tabs:
- https://aurora-opensource.github.io/au/main/install/
- http://127.0.0.1:8000/au/install/

Fixes #301.
  • Loading branch information
chiphogg authored Oct 21, 2024
1 parent fb03848 commit 06b074c
Showing 1 changed file with 150 additions and 155 deletions.
305 changes: 150 additions & 155 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ header file. For the latter approach, there are two options:

## Choosing a method

You should consider several factors before you decide how to install the Au library, such as:
These days, Au supports both bazel and CMake build systems natively. We also have community support
for the most popular C++ package managers, conan and vcpkg. Setup via any of these methods is
pretty quick, so **just doing a full install is usually best**.

- Tradeoffs in setup time, unit selection, and flexibility.
- Whether you're installing for production, or just trying it out.
- Your build system.
The main reason to consider a single-file approach is if you're not using any of these build
systems: clearly, a single file works with any build system imaginable. The _pre-built_ single file
packages are also the quickest way to start playing with the library.

Here's an overview of the tradeoffs involved.

Expand All @@ -32,217 +34,89 @@ Here's an overview of the tradeoffs involved.
<table>
<tr>
<th rowspan=2></th>
<th colspan=2>Full Install</th>
<th colspan=2>Single File</th>
<th colspan=3>Full Install</th>
</tr>
<tr>
<td>bazel, CMake, conan, vcpkg</td>
<td>Other build systems</td>
<td>Pre-built</td>
<td>Custom</td>
<td>bazel</td>
<td>CMake</td>
<td>conan, vcpkg, ...</td>
</tr>
<tr>
<td>Setup time</td>
<td class="best">~1 min</td>
<td class="good">~10 min</td>
<td class="good">~10 min</td>
<td class="good">~10 min</td>
<td class="poor">Not <i>yet</i> supported<br>(use <b>single-file</b> instead for now)</td>
<td class="good">Fast (a few minutes)</td>
<td rowspan="4" class="poor">Full Install unsupported (use single-file instead)</td>
<td class="best">Instant</td>
<td class="good">Fast (a few minutes)</td>
</tr>
<tr>
<td>Unit selection</td>
<td class="best">Any units desired, <i>without</i> needing "reinstall"</td>
<td class="fair">Base units only<br>(or too many units)</td>
<td class="good">Any units desired</td>
<td colspan=3 class="best">Any units desired, <i>without</i> needing "reinstall"</td>
</tr>
<tr>
<td>Compile time cost</td>
<td class="good">~10 units</td>
<td class="best"><i>Each file</i> only pays for the units it uses</td>
<td class="good">Cost of core, plus ~10 units</td>
<td class="good">Very competitive up to a few dozen units</td>
<td colspan=3 class="best"><i>Each file</i> only pays for the units it uses</td>
</tr>
<tr>
<td>Flexibility</td>
<td class="best">
Include I/O, testing utilities, individual units as desired, on a per-file basis
</td>
<td colspan=2 class="fair">
Awkward: would need to download <pre>io.hh</pre> and/or <pre>testing.hh</pre> separately, and
modify their includes manually
</td>
<td colspan=3 class="best">
Include I/O, testing utilities, individual units as desired, on a per-file basis
</td>
</tr>
</table>

So, which should _you_ use?

``` mermaid
graph TD
Usage[What's your use case?]
SetupTime[Got 10 minutes for setup?]
BuildSystem[What's your build system?]
UsePreBuilt[Use pre-built single file]
UseCustom[Use custom single file]
UseFullInstall[Use full install]
Usage -->|Just playing around with Au| SetupTime
SetupTime -->|No! Just let me start!| UsePreBuilt
SetupTime -->|Sure| UseCustom
Usage -->|Ready to use in my project!| BuildSystem
BuildSystem -->|bazel| UseFullInstall
BuildSystem -->|CMake| UseFullInstall
BuildSystem -->|other| UseCustom
```

## Installation instructions

Here are the instructions for each installation method we support.

### Single file {#single-file}

The Au library can be packaged as a single header file, which you can include in your project just
like any other header. This works with any build system!

To take this approach, obtain the single file by one of the methods described below. Then, put it
inside a `third_party` folder (for example, as `third_party/au.hh`). Now you're up and running with
Au!

Every single-file package automatically includes the following features:

- Basic "unit container" types: [`Quantity`](./reference/quantity.md),
[`QuantityPoint`](./reference/quantity_point.md)
- [Magnitude](./reference/magnitude.md) types and values, including constants for any integer such
as `mag<5280>()`.
- All [prefixes](./reference/prefix.md) for SI (`kilo`, `mega`, ...) and informational (`kibi`,
`mebi`, ...) quantities.
- [Math functions](./reference/math.md), including unit-aware rounding and inverses, trigonometric
functions, square roots, and so on.
- _Bidirectional implicit conversion_ between `Quantity` types and any [equivalent counterparts in the
`std::chrono` library](./reference/corresponding_quantity.md#chrono-duration).

Here are the two ways to get a single-file packaging of the library.

#### Pre-built single file

!!! tip
This approach is mainly for _playing_ with the library. It's very fast to get up and running,
but it's not the best choice as the "production" installation of your library.

For a single-file approach, most users will be much better served by the next section, which
explains how to customize it to get exactly the units you want.

We provide pre-generated single-file versions of the library, automatically generated from the
latest commit in the repo:

- [`au.hh`](./au.hh)
- [`au_noio.hh`](./au_noio.hh)
(Same as above, but with `<iostream>` support stripped out)

These include very few units (to keep compile times short). However, _combinations_ of these units
should get you any other unit you're likely to want. The units we include are:

- Every SI base unit (`seconds`, `meters`, `kilo(grams)`, `amperes`, `kelvins`, `moles`, `candelas`)
- Base units for angles and information (`radians`, `bits`)
- A base dimensionless unit (`unos`)

!!! note
_How_ do you go about constructing other units from these? By **composing** them. For example,
you can make [other coherent SI units](https://www.nist.gov/pml/owm/metric-si/si-units) like
this:

```cpp
constexpr auto newtons = kilo(gram) * meters / squared(second);
```

Now you can call, say, `newtons(10)` and get a quantity equivalent to 10 Newtons. You can also
**scale** a unit by multiplying by Magnitude objects. For example:

```cpp
constexpr auto degrees = radians * Magnitude<Pi>{} / mag<180>();
```

These will "work", in the sense of producing correct results. But these ad hoc unit definitions
are far less usable than [fully defined units](./howto/new-units.md). Both the type names and
the unit symbols will be needlessly complicated.

Again, we recommend following the directions in the next section to get _exactly_ the units you
care about.

??? warning "Pre-built files with all units"
We also provide pre-built files with every unit the library knows about.

We don't advertise this option widely, because the library's compile time slowdown is largely
proportional to the number of units included in a translation unit. Thus, not only will this
configuration be the slowest of all, but _it will get increasingly slower as the library gets
better over time_ (by supporting more and more units out of the box).

Therefore, these files are only for use cases where _you don't care about compile time_. The
primary example is [the Compiler Explorer ("godbolt")](https://godbolt.org/z/KrvfhP4M3).

**If you don't care about compile times**, here are the files:

- [`au_all_units.hh`](./au_all_units.hh)
- [`au_all_units_noio.hh`](./au_all_units_noio.hh)
(Same as above, but with `<iostream>` support stripped out)


#### Custom single file

It's easy to package the library in a _custom_ single file with _exactly_ the units you need.
Here's how:

1. **Clone the repo**. Go to the [aurora-opensource/au](https://github.com/aurora-opensource/au)
repo, and follow the typical instructions.
- If you're just a _user_ of Au, not a _contributor_, this should be:<br>
`git clone https://github.com/aurora-opensource/au.git`

2. **Run the script**. `tools/bin/make-single-file --units meters seconds newtons > ~/au.hh`
creates a file, `~/au.hh`, which packages the entire library in a single file with these three
units.
- To see the full list of available units, search the `.hh` files in the `au/units/` folder. For
example, `meters` will include the contents of `au/units/meters.hh`.
- Provide the `--noio` flag if you prefer to avoid the expense of the `<iostream>` library.

Now you have a file, `~/au.hh`, which you can add to your `third_party` folder.

### Full library installation {#full}

#### bazel

1. **Choose your Au version**.
- This can be a tag, or a commit hash. Let's take `0.3.4` as an example.
- This can be a tag, or a commit hash. Let's take `0.3.5` as an example.

2. **Form the URL to the archive**.
- For `0.3.4`, this would be:
- For `0.3.5`, this would be:
```
https://github.com/aurora-opensource/au/releases/download/0.3.4/au-0.3.4.tar.gz
https://github.com/aurora-opensource/au/releases/download/0.3.5/au-0.3.5.tar.gz
NOTE: Your au version ID goes HERE ^^^^^ ^^^^^
```


3. **Compute your SHA256 hash**.
1. Follow the URL from the previous step to download the archive.
2. Compute the SHA256 hash: `sha256sum au-0.3.4.tar.gz`
2. Compute the SHA256 hash: `sha256sum au-0.3.5.tar.gz`
3. The first token that appears is the hash. Save it for the next step.

4. **Add `http_archive` rule to `WORKSPACE`**.
- Follow this pattern:
```python
http_archive(
name = "au",
sha256 = "dd0f97e2720f02e3c5531a912c21b8eb889fcb984bac5f5f8b0f00e16b839216",
strip_prefix = "au-0.3.4",
urls = ["https://github.com/aurora-opensource/au/releases/download/0.3.4/au-0.3.4.tar.gz"],
sha256 = "7ec826dc42968dc1633de56e4f9d06e70de73e820d2ac4788e8453343a622c9b",
strip_prefix = "au-0.3.5",
urls = ["https://github.com/aurora-opensource/au/releases/download/0.3.5/au-0.3.5.tar.gz"],
)
```
- In particular, here's how to fill out the fields:
- `sha256`: Use the SHA256 hash you got from step 3.
- `strip_prefix`: write `"au-0.3.4"`, except use your ID from step 1 instead of `0.3.4`.
- `strip_prefix`: write `"au-0.3.5"`, except use your ID from step 1 instead of `0.3.5`.
- `urls`: This should be a list, whose only entry is the URL you formed in step 2.

At this point, the Au library is installed, and you can use it in your project!

Here are the headers provided by each Au target. To use, add the "Dependency" to your `deps`
attribute, and include the appropriate files.
Here are the headers provided by each Au target. To use, add the entry from the "Dependency" column
to your `deps` attribute, and include the appropriate files.

| Dependency | Headers provided | Notes |
|------------|------------------|-------|
Expand Down Expand Up @@ -345,3 +219,124 @@ In either case, here are the main targets and include files provided by the Au l
```

<script src="../assets/hrh4.js" async=false defer=false></script>

#### Package managers (conan, vcpkg)

If you're using these in your project, we assume you already know how to add new libraries. These
methods have "community support", which means:

- The recipes are added and maintained by external users
- Au's maintainers will provide our _best effort_ to respond to issues, but we'll need to rely on
users of these package managers to help us reproduce and understand them

Each package manager contains setup instructions on its page for Au. Here are the packages:

- **Conan:** [au](https://conan.io/center/recipes/au)
- **vcpkg:** [aurora-au](https://vcpkg.link/ports/aurora-au)

This comment has been minimized.

Copy link
@andre-nguyen

andre-nguyen Oct 21, 2024

@chiphogg fyi vcpkg.link is a third party whereas vcpkg.io is the official website https://vcpkg.io/en/package/aurora-au

This comment has been minimized.

Copy link
@chiphogg

chiphogg Oct 21, 2024

Author Contributor

Thanks! I hate to say it, but I think GitHub Copilot may have led me astray here. 😳

This comment has been minimized.

Copy link
@chiphogg

chiphogg Oct 22, 2024

Author Contributor

Actually, this wasn't GitHub copilot --- I remember now. I had googled for "vcpkg aurora-au", and this was the first result. The vcpkg.io link doesn't even show up there yet!


### Single file {#single-file}

The Au library can be packaged as a single header file, which you can include in your project just
like any other header. This works with any build system!

To take this approach, obtain the single file by one of the methods described below. Then, put it
inside a `third_party` folder (for example, as `third_party/au.hh`). Now you're up and running with
Au!

Every single-file package automatically includes the following features:

- Basic "unit container" types: [`Quantity`](./reference/quantity.md),
[`QuantityPoint`](./reference/quantity_point.md)
- [Magnitude](./reference/magnitude.md) types and values, including constants for any integer such
as `mag<5280>()`.
- All [prefixes](./reference/prefix.md) for SI (`kilo`, `mega`, ...) and informational (`kibi`,
`mebi`, ...) quantities.
- [Math functions](./reference/math.md), including unit-aware rounding and inverses, trigonometric
functions, square roots, and so on.
- _Bidirectional implicit conversion_ between `Quantity` types and any [equivalent counterparts in the
`std::chrono` library](./reference/corresponding_quantity.md#chrono-duration).

Here are the two ways to get a single-file packaging of the library.

#### Pre-built single file

!!! tip
This approach is mainly for _playing_ with the library. It's very fast to get up and running,
but it's not the best choice as the "production" installation of your library.

For a single-file approach, most users will be much better served by the next section, which
explains how to customize it to get exactly the units you want.

We provide pre-generated single-file versions of the library, automatically generated from the
latest commit in the repo:

- [`au.hh`](./au.hh)
- [`au_noio.hh`](./au_noio.hh)
(Same as above, but with `<iostream>` support stripped out)

These include very few units (to keep compile times short). However, _combinations_ of these units
should get you any other unit you're likely to want. The units we include are:

- Every SI base unit (`seconds`, `meters`, `kilo(grams)`, `amperes`, `kelvins`, `moles`, `candelas`)
- Base units for angles and information (`radians`, `bits`)
- A base dimensionless unit (`unos`)

!!! note
_How_ do you go about constructing other units from these? By **composing** them. For example,
you can make [other coherent SI units](https://www.nist.gov/pml/owm/metric-si/si-units) like
this:

```cpp
constexpr auto newtons = kilo(gram) * meters / squared(second);
```

Now you can call, say, `newtons(10)` and get a quantity equivalent to 10 Newtons. You can also
**scale** a unit by multiplying by Magnitude objects. For example:

```cpp
constexpr auto degrees = radians * Magnitude<Pi>{} / mag<180>();
```

These will "work", in the sense of producing correct results. But these ad hoc unit definitions
are far less usable than [fully defined units](./howto/new-units.md). Both the type names and
the unit symbols will be needlessly complicated.

Again, we recommend following the directions in the next section to get _exactly_ the units you
care about.

??? warning "Pre-built files with all units"
We also provide pre-built files with every unit the library knows about.

We don't advertise this option widely, because the library's compile time slowdown is largely
proportional to the number of units included in a translation unit. Thus, not only will this
configuration be the slowest of all, but _it will get increasingly slower as the library gets
better over time_ (by supporting more and more units out of the box).

Therefore, these files are only for use cases where _you don't care about compile time_. The
primary example is [the Compiler Explorer ("godbolt")](https://godbolt.org/z/KrvfhP4M3).

**If you don't care about compile times**, here are the files:

- [`au_all_units.hh`](./au_all_units.hh)
- [`au_all_units_noio.hh`](./au_all_units_noio.hh)
(Same as above, but with `<iostream>` support stripped out)


#### Custom single file

It's easy to package the library in a _custom_ single file with _exactly_ the units you need.
Here's how:

1. **Clone the repo**. Go to the [aurora-opensource/au](https://github.com/aurora-opensource/au)
repo, and follow the typical instructions.
- If you're just a _user_ of Au, not a _contributor_, this should be:<br>
`git clone https://github.com/aurora-opensource/au.git`

2. **Run the script**. `tools/bin/make-single-file --units meters seconds newtons > ~/au.hh`
creates a file, `~/au.hh`, which packages the entire library in a single file with these three
units.
- To see the full list of available units, search the `.hh` files in the `au/units/` folder. For
example, `meters` will include the contents of `au/units/meters.hh`.
- Provide the `--noio` flag if you prefer to avoid the expense of the `<iostream>` library.

Now you have a file, `~/au.hh`, which you can add to your `third_party` folder.

0 comments on commit 06b074c

Please sign in to comment.