1# Abseil FAQ 2 3## Is Abseil the right home for my utility library? 4 5Most often the answer to the question is "no." As both the [About 6Abseil](https://abseil.io/about/) page and our [contributing 7guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines) 8explain, Abseil contains a variety of core C++ library code that is widely used 9at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be 10used as a dependency by Google's open source C++ projects. While we do hope that 11Abseil is also useful to the C++ community at large, this added constraint also 12means that we are unlikely to accept a contribution of utility code that isn't 13already widely used by Google. 14 15## How to I set the C++ dialect used to build Abseil? 16 17The short answer is that whatever mechanism you choose, you need to make sure 18that you set this option consistently at the global level for your entire 19project. If, for example, you want to set the C++ dialect to C++17, with 20[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the 21compiler, there several ways to do this: 22* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build 23 --cxxopt=-std=c++17 ...`) 24* Set the environment variable `BAZEL_CXXOPTS` (for example, 25 `BAZEL_CXXOPTS=-std=c++17`) 26* Add `build --cxxopt=-std=c++17` to your [`.bazelrc` 27 file](https://docs.bazel.build/versions/master/guide.html#bazelrc) 28 29If you are using CMake as the build system, you'll need to add a line like 30`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you 31are developing a library designed to be used by other clients, you should 32instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard 33required by each of your library targets via `target_compile_features`. See the 34[CMake build 35instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) 36for more information. 37 38For a longer answer to this question and to understand why some other approaches 39don't work, see the answer to ["What is ABI and why don't you recommend using a 40pre-compiled version of 41Abseil?"](#what-is-abi-and-why-dont-you-recommend-using-a-pre-compiled-version-of-abseil) 42 43## What is ABI and why don't you recommend using a pre-compiled version of Abseil? 44 45For the purposes of this discussion, you can think of 46[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the 47compiled representation of the interfaces in code. This is in contrast to 48[API](https://en.wikipedia.org/wiki/Application_programming_interface), which 49you can think of as the interfaces as defined by the code itself. [Abseil has a 50strong promise of API compatibility, but does not make any promise of ABI 51compatibility](https://abseil.io/about/compatibility). Let's take a look at what 52this means in practice. 53 54You might be tempted to do something like this in a 55[Bazel](https://bazel.build/) `BUILD` file: 56 57``` 58# DON'T DO THIS!!! 59cc_library( 60 name = "my_library", 61 srcs = ["my_library.cc"], 62 copts = ["-std=c++17"], # May create a mixed-mode compile! 63 deps = ["@com_google_absl//absl/strings"], 64) 65``` 66 67Applying `-std=c++17` to an individual target in your `BUILD` file is going to 68compile that specific target in C++17 mode, but it isn't going to ensure the 69Abseil library is built in C++17 mode, since the Abseil library itself is a 70different build target. If your code includes an Abseil header, then your 71program may contain conflicting definitions of the same 72class/function/variable/enum, etc. As a rule, all compile options that affect 73the ABI of a program need to be applied to the entire build on a global basis. 74 75C++ has something called the [One Definition 76Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't 77allow multiple definitions of the same class/function/variable/enum, etc. ODR 78violations sometimes result in linker errors, but linkers do not always catch 79violations. Uncaught ODR violations can result in strange runtime behaviors or 80crashes that can be hard to debug. 81 82If you build the Abseil library and your code using different compile options 83that affect ABI, there is a good chance you will run afoul of the One Definition 84Rule. Examples of GCC compile options that affect ABI include (but aren't 85limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`), 86code generation flags (e.g. `-fexceptions`), and preprocessor defines 87(e.g. `-DNDEBUG`). 88 89If you use a pre-compiled version of Abseil, (for example, from your Linux 90distribution package manager or from something like 91[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to 92ensure ABI compatibility across the components of your program. The only way you 93can be sure your program is going to be correct regarding ABI is to ensure 94you've used the exact same compile options as were used to build the 95pre-compiled library. This does not mean that Abseil cannot work as part of a 96Linux distribution since a knowledgeable binary packager will have ensured that 97all packages have been built with consistent compile options. This is one of the 98reasons we warn against - though do not outright reject - using Abseil as a 99pre-compiled library. 100 101Another possible way that you might afoul of ABI issues is if you accidentally 102include two versions of Abseil in your program. Multiple versions of Abseil can 103end up within the same binary if your program uses the Abseil library and 104another library also transitively depends on Abseil (resulting in what is 105sometimes called the diamond dependency problem). In cases such as this you must 106structure your build so that all libraries use the same version of Abseil. 107[Abseil's strong promise of API compatibility between 108releases](https://abseil.io/about/compatibility) means the latest "HEAD" release 109of Abseil is almost certainly the right choice if you are doing as we recommend 110and building all of your code from source. 111 112For these reasons we recommend you avoid pre-compiled code and build the Abseil 113library yourself in a consistent manner with the rest of your code. 114 115## What is "live at head" and how do I do it? 116 117From Abseil's point-of-view, "live at head" means that every Abseil source 118release (which happens on an almost daily basis) is either API compatible with 119the previous release, or comes with an automated tool that you can run over code 120to make it compatible. In practice, the need to use an automated tool is 121extremely rare. This means that upgrading from one source release to another 122should be a routine practice that can and should be performed often. 123 124We recommend you update to the [latest commit in the `master` branch of 125Abseil](https://github.com/abseil/abseil-cpp/commits/master) as often as 126possible. Not only will you pick up bug fixes more quickly, but if you have good 127automated testing, you will catch and be able to fix any [Hyrum's 128Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis 129instead of being overwhelmed by them and having difficulty isolating them if you 130wait longer between updates. 131 132If you are using the [Bazel](https://bazel.build/) build system and its 133[external dependencies](https://docs.bazel.build/versions/master/external.html) 134feature, updating the 135[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive) 136rule in your 137[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for 138`com_google_abseil` to point to the [latest commit in the `master` branch of 139Abseil](https://github.com/abseil/abseil-cpp/commits/master) is all you need to 140do. For example, on February 11, 2020, the latest commit to the master branch 141was `98eb410c93ad059f9bba1bf43f5bb916fc92a5ea`. To update to this commit, you 142would add the following snippet to your `WORKSPACE` file: 143 144``` 145http_archive( 146 name = "com_google_absl", 147 urls = ["https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip"], # 2020-02-11T18:50:53Z 148 strip_prefix = "abseil-cpp-98eb410c93ad059f9bba1bf43f5bb916fc92a5ea", 149 sha256 = "aabf6c57e3834f8dc3873a927f37eaf69975d4b28117fc7427dfb1c661542a87", 150) 151``` 152 153To get the `sha256` of this URL, run `curl -sL --output - 154https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip 155| sha256sum -`. 156 157You can commit the updated `WORKSPACE` file to your source control every time 158you update, and if you have good automated testing, you might even consider 159automating this. 160 161One thing we don't recommend is using GitHub's `master.zip` files (for example 162[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)), 163which are always the latest commit in the `master` branch, to implement live at 164head. Since these `master.zip` URLs are not versioned, you will lose build 165reproducibility. In addition, some build systems, including Bazel, will simply 166cache this file, which means you won't actually be updating to the latest 167release until your cache is cleared or invalidated. 168