Skip to content

Installation

Au can be installed in multiple ways. First, we’ll help you decide which one is right for you. Then, we’ll provide full instructions for each option.

Broadly, you can either do a “full install” of the library, or you can package it into a single header file. For the latter approach, there are two options:

  • Pre-built versions you can download right away.
  • Custom versions with exactly the units you choose.

Choosing a method

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.

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.

Legend Unsupported Fair Good Best
Full Install Single File
bazel, CMake, conan, vcpkg Other build systems Pre-built Custom
Setup time Fast (a few minutes) Full Install unsupported (use single-file instead) Instant Fast (a few minutes)
Unit selection Any units desired, without needing "reinstall" Base units only
(or too many units)
Any units desired
Compile time cost Each file only pays for the units it uses Cost of core, plus ~10 units Very competitive up to a few dozen units
Flexibility Include I/O, testing utilities, individual units as desired, on a per-file basis Awkward: would need to download
io.hh
and/or
testing.hh
separately, and modify their includes manually

Compiler warning flags

Whichever method you choose, there’s one property we ask you to check: Au’s headers should not be on a “system” include path (that is, -isystem on gcc and clang, or /external:I on MSVC).

The reason is Au’s policy on compiler warnings: we aim to raise the same warnings and errors for Quantity that your compiler flags would raise for the underlying raw numbers — no more, and no less. Since Au is header-only, the numeric conversions physically happen inside Au’s headers. If those headers are “system” headers, your compiler will silently suppress every one of those warnings, and there’s nothing we can do about it from inside the library. See the required build configuration for the full explanation.

Help us keep this advice accurate

We’ve tested the guidance below where we can. The bazel and CMake instructions were checked by building a real client project against Au, with both gcc and clang. Other parts rest on documented behavior that we can’t easily exercise: notably MSVC’s /external:I, and the conan and vcpkg packages, which are community maintained. Build systems also change their defaults over time, and this page won’t always notice.

So treat it as our best current understanding rather than a guarantee. If you follow it and Au still adds or subtracts a warning relative to the equivalent raw-number code, please file an issue. It’s either a bug in Au, or a gap in these instructions — and we want to fix both.

Here’s what to check for each installation method.

Default behavior: correct; nothing to do. Bazel passes external repositories’ include paths as -iquote, which is not a system include path.

The setting to watch out for is the external_include_paths feature, which adds -isystem for every external repository. If your project enables it (typically via --features=external_include_paths in .bazelrc), you can turn it back off:

# In .bazelrc:
build --features=-external_include_paths

You can verify what your build actually passes:

bazel aquery 'mnemonic("CppCompile", //your:target)' | grep -A1 -- -isystem

gcc and clang differ here

With this feature enabled, Bazel passes both -iquote and -isystem for the same external repository directory. In that situation, clang keeps the warnings (because the quoted include "au/au.hh" resolves via the -iquote path), while gcc suppresses them. Don’t rely on this: disable the feature, or at least test with the compiler you care about.

Default behavior: correct; nothing to do. Targets brought in this way are ordinary (non-imported) targets, whose include directories are not treated as system directories.

Just be sure not to opt in to the system treatment, which CMake 3.25 and newer offer via the SYSTEM keyword:

FetchContent_Declare(
  Au
  # ...
  SYSTEM  # <--- Don't do this for Au!
)

The same applies to add_subdirectory(... SYSTEM), and to setting the SYSTEM directory or target property for Au.

Default behavior: warnings suppressed; action required. These methods all deliver Au as an imported target, and CMake treats an imported target’s INTERFACE_INCLUDE_DIRECTORIES as system directories by default.

To get Au’s intended warning behavior, turn this off after finding the package:

find_package(Au REQUIRED)

# CMake 3.25 and newer:
set_target_properties(Au::au PROPERTIES SYSTEM OFF)

# CMake 3.23 and 3.24 (deprecated in 3.25):
# set_target_properties(Au::au PROPERTIES IMPORTED_NO_SYSTEM TRUE)

Alternatively, you can set NO_SYSTEM_FROM_IMPORTED on your own target (or as a directory property). This works on much older CMake versions, but note that it applies to all of that target’s imported dependencies, not just Au.

We’ve verified this for a find_package installation. For conan and vcpkg, we know the underlying cause is the same CMake default, but each has its own machinery for generating package config files, so it’s possible that they mark the include directories as “system” in a way that these properties don’t override. If you find that to be the case, please let us know!

You’re in control. Add the folder holding au.hh with -I (or /I on MSVC), not -isystem (or /external:I). If you keep it in, say, third_party/, and your build treats that whole folder as external, consider putting Au somewhere else.

Installation instructions

Here are the instructions for each installation method we support.

Full library installation

bazel

Au is available through the Bazel Central Registry. Choose your version (take 0.5.1 as an example) and the dependency to your MODULE.bazel:

bazel_dep(name = "au", version = "0.5.1")

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 entry from the “Dependency” column to your deps attribute, and include the appropriate files.

Dependency Headers provided Notes
@au//au "au/au.hh"
"au/fwd.hh"
"au/units/*.hh"
"au/units/*_fwd.hh"
"au/units/literals/*.hh"
"au/constants/*.hh"
Core library functionality. See all available units, unit literals, and constants
@au//au:io "au/io.hh" operator<< support
@au//au:std_format "au/std_format.hh" std::format support1
@au//au:testing "au/testing.hh" Utilities for writing googletest tests
Note: testonly = True
Legacy WORKSPACE
  1. Choose your Au version.

    • 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.5, this would be:
      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.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:
      http_archive(
          name = "au",
          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.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.
@au//au:testing and googletest

This note applies only to legacy WORKSPACE users. If you use bzlmod, you can ignore this.

The @au//au:testing target depends on googletest via the @googletest repository name. If your WORKSPACE defines googletest with a different name (such as @com_google_googletest), you’ll need to add a repo_mapping to your Au dependency:

http_archive(
    name = "au",
    # ... other fields ...
    repo_mapping = {"@googletest": "@com_google_googletest"},  # Map to your googletest name
)

Or for local_repository:

local_repository(
    name = "au",
    path = "path/to/au",
    repo_mapping = {"@googletest": "@com_google_googletest"},  # Map to your googletest name
)

CMake

There are two ways to include the Au library in your CMake project.

  1. (Recommended) Use the FetchContent module to download the library directly from GitHub.

  2. Install the library to the system, and use find_package.

We recommend FetchContent because each project can get the exact version of Au that they need, and can update it independently of other projects. FetchContent also means you don’t need to manually clone the Au repo, or build and run the tests. On the other hand, if you want a single global system-wide version of Au, then you can install it to the system, and simply use find_package.

In either case, here are the main targets and include files provided by the Au library:

Target Headers provided Notes
Au::au "au/au.hh"
"au/fwd.hh"
"au/io.hh"
"au/std_format.hh"1
"au/units/*.hh"
"au/units/*_fwd.hh"
"au/units/literals/*.hh"
"au/constants/*.hh"
Core library functionality. See all available units and unit literals
Au::testing "au/testing.hh" Utilities for writing googletest tests

Note

These instructions are for adding Au to a project that uses CMake, not building Au itself using CMake.

Au is a bazel-first project, so most Au development would normally be done using bazel. However, we do have instructions for doing this with CMake as well: see the find_package tab below.

Add the following to your CMakeLists.txt file:

include(FetchContent)
FetchContent_Declare(
  Au
  GIT_REPOSITORY https://github.com/aurora-opensource/au
  GIT_TAG "main"  # Or a specific tag.
  EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(Au)

You should now be able to depend on Au targets, such as Au::au or Au::testing, and include headers from them, such as #include "au/au.hh" or #include "au/testing.hh".

Before you can use find_package, you need to install the library to your system. This means cloning the repo, building the library, running the tests, and installing it.

First, clone the repository.

git clone https://github.com/aurora-opensource/au.git
cd au

If you want a specific release, check out the tag you want. Note that the first version of Au that supports CMake is 0.3.5.

# Optional, but recommended:
git checkout "0.4.1"  # Or whichever tag you prefer.

Now, build and test the library. These commands will include both the explicit tests, and also several CMake-generated tests to make sure that the includes are set up correctly.

# CMake is a "meta build system", not a build system.
# This first command generates the actual build files.
cmake -S . -B cmake/build -DCMAKE_VERIFY_INTERFACE_HEADER_SETS=TRUE

# This command builds Au, checks include paths, and runs unit tests.
cmake \
  --build cmake/build \
  --target \
    all \
    all_verify_interface_header_sets \
    test

If the tests pass, you can install the library to your system.

sudo cmake --install cmake/build

At this point, the Au CMake library is installed to your system, and can be found via the usual find_package mechanism!

find_package(Au)

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:

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:

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:

Includes std::format? Includes <iostream>? Filename
No Yes au.hh
No No au_noio.hh
Yes Yes au_stdformat.hh
Yes No au_stdformat_noio.hh

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 like this:

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:

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. 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.

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”).

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

Includes std::format? Includes <iostream>? Filename
No Yes au_all_units.hh
No No au_all_units_noio.hh
Yes Yes au_all_units_stdformat.hh
Yes No au_all_units_stdformat_noio.hh

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 repo, and follow the typical instructions.

    • If you’re just a user of Au, not a contributor, this should be:
      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".
    • Similarly, to see the full list of available constants, search the .hh files in the au/constants/ folder. For example, speed_of_light will include the contents of "au/constants/speed_of_light.hh", which provides the constant au::SPEED_OF_LIGHT.
    • To include unit literals, pass the --literals flag with the units whose literals you want: for example,
      tools/bin/make-single-file --units meters seconds --literals meters.
      Each entry named here also pulls in the unit itself, so --literals meters works even if meters isn’t in the --units list.
    • 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.


  1. Do not include "au/std_format.hh" unless you know that both your compiler and your build configuration fully supports std::format. This requires at least C++20, but many compilers with nominal C++20 support do not actually support std::format