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