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