1//
2// Copyright 2017 The Abseil Authors.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// https://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// -----------------------------------------------------------------------------
17// File: config.h
18// -----------------------------------------------------------------------------
19//
20// This header file defines a set of macros for checking the presence of
21// important compiler and platform features. Such macros can be used to
22// produce portable code by parameterizing compilation based on the presence or
23// lack of a given feature.
24//
25// We define a "feature" as some interface we wish to program to: for example,
26// a library function or system call. A value of `1` indicates support for
27// that feature; any other value indicates the feature support is undefined.
28//
29// Example:
30//
31// Suppose a programmer wants to write a program that uses the 'mmap()' system
32// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to
33// selectively include the `mmap.h` header and bracket code using that feature
34// in the macro:
35//
36// #include "absl/base/config.h"
37//
38// #ifdef ABSL_HAVE_MMAP
39// #include "sys/mman.h"
40// #endif //ABSL_HAVE_MMAP
41//
42// ...
43// #ifdef ABSL_HAVE_MMAP
44// void *ptr = mmap(...);
45// ...
46// #endif // ABSL_HAVE_MMAP
47
48#ifndef ABSL_BASE_CONFIG_H_
49#define ABSL_BASE_CONFIG_H_
50
51// Included for the __GLIBC__ macro (or similar macros on other systems).
52#include <limits.h>
53
54#ifdef __cplusplus
55// Included for __GLIBCXX__, _LIBCPP_VERSION
56#include <cstddef>
57#endif // __cplusplus
58
59#if defined(__APPLE__)
60// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED,
61// __IPHONE_8_0.
62#include <Availability.h>
63#include <TargetConditionals.h>
64#endif
65
66#include "absl/base/policy_checks.h"
67
68// -----------------------------------------------------------------------------
69// Compiler Feature Checks
70// -----------------------------------------------------------------------------
71
72// ABSL_HAVE_BUILTIN()
73//
74// Checks whether the compiler supports a Clang Feature Checking Macro, and if
75// so, checks whether it supports the provided builtin function "x" where x
76// is one of the functions noted in
77// https://clang.llvm.org/docs/LanguageExtensions.html
78//
79// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check.
80// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html
81#ifdef __has_builtin
82#define ABSL_HAVE_BUILTIN(x) __has_builtin(x)
83#else
84#define ABSL_HAVE_BUILTIN(x) 0
85#endif
86
87// ABSL_HAVE_TLS is defined to 1 when __thread should be supported.
88// We assume __thread is supported on Linux when compiled with Clang or compiled
89// against libstdc++ with _GLIBCXX_HAVE_TLS defined.
90#ifdef ABSL_HAVE_TLS
91#error ABSL_HAVE_TLS cannot be directly set
92#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
93#define ABSL_HAVE_TLS 1
94#endif
95
96// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
97//
98// Checks whether `std::is_trivially_destructible<T>` is supported.
99//
100// Notes: All supported compilers using libc++ support this feature, as does
101// gcc >= 4.8.1 using libstdc++, and Visual Studio.
102#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
103#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
104#elif defined(_LIBCPP_VERSION) || \
105 (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \
106 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
107 defined(_MSC_VER)
108#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
109#endif
110
111// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
112//
113// Checks whether `std::is_trivially_default_constructible<T>` and
114// `std::is_trivially_copy_constructible<T>` are supported.
115
116// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
117//
118// Checks whether `std::is_trivially_copy_assignable<T>` is supported.
119
120// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with
121// either libc++ or libstdc++, and Visual Studio (but not NVCC).
122#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
123#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
124#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE)
125#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set
126#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \
127 (!defined(__clang__) && defined(__GNUC__) && \
128 (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \
129 (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \
130 (defined(_MSC_VER) && !defined(__NVCC__))
131#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
132#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
133#endif
134
135// ABSL_HAVE_THREAD_LOCAL
136//
137// Checks whether C++11's `thread_local` storage duration specifier is
138// supported.
139#ifdef ABSL_HAVE_THREAD_LOCAL
140#error ABSL_HAVE_THREAD_LOCAL cannot be directly set
141#elif defined(__APPLE__)
142// Notes:
143// * Xcode's clang did not support `thread_local` until version 8, and
144// even then not for all iOS < 9.0.
145// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator
146// targeting iOS 9.x.
147// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time
148// making __has_feature unreliable there.
149//
150// Otherwise, `__has_feature` is only supported by Clang so it has be inside
151// `defined(__APPLE__)` check.
152#if __has_feature(cxx_thread_local) && \
153 !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
154#define ABSL_HAVE_THREAD_LOCAL 1
155#endif
156#else // !defined(__APPLE__)
157#define ABSL_HAVE_THREAD_LOCAL 1
158#endif
159
160// There are platforms for which TLS should not be used even though the compiler
161// makes it seem like it's supported (Android NDK < r12b for example).
162// This is primarily because of linker problems and toolchain misconfiguration:
163// Abseil does not intend to support this indefinitely. Currently, the newest
164// toolchain that we intend to support that requires this behavior is the
165// r11 NDK - allowing for a 5 year support window on that means this option
166// is likely to be removed around June of 2021.
167// TLS isn't supported until NDK r12b per
168// https://developer.android.com/ndk/downloads/revision_history.html
169// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in
170// <android/ndk-version.h>. For NDK < r16, users should define these macros,
171// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11.
172#if defined(__ANDROID__) && defined(__clang__)
173#if __has_include(<android/ndk-version.h>)
174#include <android/ndk-version.h>
175#endif // __has_include(<android/ndk-version.h>)
176#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
177 defined(__NDK_MINOR__) && \
178 ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
179#undef ABSL_HAVE_TLS
180#undef ABSL_HAVE_THREAD_LOCAL
181#endif
182#endif // defined(__ANDROID__) && defined(__clang__)
183
184// Emscripten doesn't yet support `thread_local` or `__thread`.
185// https://github.com/emscripten-core/emscripten/issues/3502
186#if defined(__EMSCRIPTEN__)
187#undef ABSL_HAVE_TLS
188#undef ABSL_HAVE_THREAD_LOCAL
189#endif // defined(__EMSCRIPTEN__)
190
191// ABSL_HAVE_INTRINSIC_INT128
192//
193// Checks whether the __int128 compiler extension for a 128-bit integral type is
194// supported.
195//
196// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is
197// supported, but we avoid using it in certain cases:
198// * On Clang:
199// * Building using Clang for Windows, where the Clang runtime library has
200// 128-bit support only on LP64 architectures, but Windows is LLP64.
201// * On Nvidia's nvcc:
202// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions
203// actually support __int128.
204#ifdef ABSL_HAVE_INTRINSIC_INT128
205#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set
206#elif defined(__SIZEOF_INT128__)
207#if (defined(__clang__) && !defined(_WIN32)) || \
208 (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
209 (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
210#define ABSL_HAVE_INTRINSIC_INT128 1
211#elif defined(__CUDACC__)
212// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a
213// string explaining that it has been removed starting with CUDA 9. We use
214// nested #ifs because there is no short-circuiting in the preprocessor.
215// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined.
216#if __CUDACC_VER__ >= 70000
217#define ABSL_HAVE_INTRINSIC_INT128 1
218#endif // __CUDACC_VER__ >= 70000
219#endif // defined(__CUDACC__)
220#endif // ABSL_HAVE_INTRINSIC_INT128
221
222// ABSL_HAVE_EXCEPTIONS
223//
224// Checks whether the compiler both supports and enables exceptions. Many
225// compilers support a "no exceptions" mode that disables exceptions.
226//
227// Generally, when ABSL_HAVE_EXCEPTIONS is not defined:
228//
229// * Code using `throw` and `try` may not compile.
230// * The `noexcept` specifier will still compile and behave as normal.
231// * The `noexcept` operator may still return `false`.
232//
233// For further details, consult the compiler's documentation.
234#ifdef ABSL_HAVE_EXCEPTIONS
235#error ABSL_HAVE_EXCEPTIONS cannot be directly set.
236
237#elif defined(__clang__)
238// TODO(calabrese)
239// Switch to using __cpp_exceptions when we no longer support versions < 3.6.
240// For details on this check, see:
241// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
242#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
243#define ABSL_HAVE_EXCEPTIONS 1
244#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
245
246// Handle remaining special cases and default to exceptions being supported.
247#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \
248 !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \
249 !(defined(_MSC_VER) && !defined(_CPPUNWIND))
250#define ABSL_HAVE_EXCEPTIONS 1
251#endif
252
253// -----------------------------------------------------------------------------
254// Platform Feature Checks
255// -----------------------------------------------------------------------------
256
257// Currently supported operating systems and associated preprocessor
258// symbols:
259//
260// Linux and Linux-derived __linux__
261// Android __ANDROID__ (implies __linux__)
262// Linux (non-Android) __linux__ && !__ANDROID__
263// Darwin (Mac OS X and iOS) __APPLE__
264// Akaros (http://akaros.org) __ros__
265// Windows _WIN32
266// NaCL __native_client__
267// AsmJS __asmjs__
268// WebAssembly __wasm__
269// Fuchsia __Fuchsia__
270//
271// Note that since Android defines both __ANDROID__ and __linux__, one
272// may probe for either Linux or Android by simply testing for __linux__.
273
274// ABSL_HAVE_MMAP
275//
276// Checks whether the platform has an mmap(2) implementation as defined in
277// POSIX.1-2001.
278#ifdef ABSL_HAVE_MMAP
279#error ABSL_HAVE_MMAP cannot be directly set
280#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
281 defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \
282 defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \
283 defined(__ASYLO__)
284#define ABSL_HAVE_MMAP 1
285#endif
286
287// ABSL_HAVE_PTHREAD_GETSCHEDPARAM
288//
289// Checks whether the platform implements the pthread_(get|set)schedparam(3)
290// functions as defined in POSIX.1-2001.
291#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
292#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set
293#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
294 defined(__ros__)
295#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1
296#endif
297
298// ABSL_HAVE_SCHED_YIELD
299//
300// Checks whether the platform implements sched_yield(2) as defined in
301// POSIX.1-2001.
302#ifdef ABSL_HAVE_SCHED_YIELD
303#error ABSL_HAVE_SCHED_YIELD cannot be directly set
304#elif defined(__linux__) || defined(__ros__) || defined(__native_client__)
305#define ABSL_HAVE_SCHED_YIELD 1
306#endif
307
308// ABSL_HAVE_SEMAPHORE_H
309//
310// Checks whether the platform supports the <semaphore.h> header and sem_open(3)
311// family of functions as standardized in POSIX.1-2001.
312//
313// Note: While Apple provides <semaphore.h> for both iOS and macOS, it is
314// explicitly deprecated and will cause build failures if enabled for those
315// platforms. We side-step the issue by not defining it here for Apple
316// platforms.
317#ifdef ABSL_HAVE_SEMAPHORE_H
318#error ABSL_HAVE_SEMAPHORE_H cannot be directly set
319#elif defined(__linux__) || defined(__ros__)
320#define ABSL_HAVE_SEMAPHORE_H 1
321#endif
322
323// ABSL_HAVE_ALARM
324//
325// Checks whether the platform supports the <signal.h> header and alarm(2)
326// function as standardized in POSIX.1-2001.
327#ifdef ABSL_HAVE_ALARM
328#error ABSL_HAVE_ALARM cannot be directly set
329#elif defined(__GOOGLE_GRTE_VERSION__)
330// feature tests for Google's GRTE
331#define ABSL_HAVE_ALARM 1
332#elif defined(__GLIBC__)
333// feature test for glibc
334#define ABSL_HAVE_ALARM 1
335#elif defined(_MSC_VER)
336// feature tests for Microsoft's library
337#elif defined(__EMSCRIPTEN__)
338// emscripten doesn't support signals
339#elif defined(__native_client__)
340#else
341// other standard libraries
342#define ABSL_HAVE_ALARM 1
343#endif
344
345// ABSL_IS_LITTLE_ENDIAN
346// ABSL_IS_BIG_ENDIAN
347//
348// Checks the endianness of the platform.
349//
350// Notes: uses the built in endian macros provided by GCC (since 4.6) and
351// Clang (since 3.2); see
352// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html.
353// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error.
354#if defined(ABSL_IS_BIG_ENDIAN)
355#error "ABSL_IS_BIG_ENDIAN cannot be directly set."
356#endif
357#if defined(ABSL_IS_LITTLE_ENDIAN)
358#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set."
359#endif
360
361#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
362 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
363#define ABSL_IS_LITTLE_ENDIAN 1
364#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
365 __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
366#define ABSL_IS_BIG_ENDIAN 1
367#elif defined(_WIN32)
368#define ABSL_IS_LITTLE_ENDIAN 1
369#else
370#error "absl endian detection needs to be set up for your compiler"
371#endif
372
373// MacOS 10.13 doesn't let you use <any>, <optional>, or <variant> even though
374// the headers exist and are publicly noted to work. See
375// https://github.com/abseil/abseil-cpp/issues/207 and
376// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
377#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \
378 defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \
379 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400
380#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1
381#else
382#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 0
383#endif
384
385// ABSL_HAVE_STD_ANY
386//
387// Checks whether C++17 std::any is available by checking whether <any> exists.
388#ifdef ABSL_HAVE_STD_ANY
389#error "ABSL_HAVE_STD_ANY cannot be directly set."
390#endif
391
392#ifdef __has_include
393#if __has_include(<any>) && __cplusplus >= 201703L && \
394 !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
395#define ABSL_HAVE_STD_ANY 1
396#endif
397#endif
398
399// ABSL_HAVE_STD_OPTIONAL
400//
401// Checks whether C++17 std::optional is available.
402#ifdef ABSL_HAVE_STD_OPTIONAL
403#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set."
404#endif
405
406#ifdef __has_include
407#if __has_include(<optional>) && __cplusplus >= 201703L && \
408 !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
409#define ABSL_HAVE_STD_OPTIONAL 1
410#endif
411#endif
412
413// ABSL_HAVE_STD_VARIANT
414//
415// Checks whether C++17 std::variant is available.
416#ifdef ABSL_HAVE_STD_VARIANT
417#error "ABSL_HAVE_STD_VARIANT cannot be directly set."
418#endif
419
420#ifdef __has_include
421#if __has_include(<variant>) && __cplusplus >= 201703L && \
422 !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
423#define ABSL_HAVE_STD_VARIANT 1
424#endif
425#endif
426
427// ABSL_HAVE_STD_STRING_VIEW
428//
429// Checks whether C++17 std::string_view is available.
430#ifdef ABSL_HAVE_STD_STRING_VIEW
431#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set."
432#endif
433
434#ifdef __has_include
435#if __has_include(<string_view>) && __cplusplus >= 201703L
436#define ABSL_HAVE_STD_STRING_VIEW 1
437#endif
438#endif
439
440// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than
441// the support for <optional>, <any>, <string_view>, <variant>. So we use
442// _MSC_VER to check whether we have VS 2017 RTM (when <optional>, <any>,
443// <string_view>, <variant> is implemented) or higher. Also, `__cplusplus` is
444// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language
445// version.
446// TODO(zhangxy): fix tests before enabling aliasing for `std::any`.
447#if defined(_MSC_VER) && _MSC_VER >= 1910 && \
448 ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402)
449// #define ABSL_HAVE_STD_ANY 1
450#define ABSL_HAVE_STD_OPTIONAL 1
451#define ABSL_HAVE_STD_VARIANT 1
452#define ABSL_HAVE_STD_STRING_VIEW 1
453#endif
454
455// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION
456// SEH exception from emplace for variant<SomeStruct> when constructing the
457// struct can throw. This defeats some of variant_test and
458// variant_exception_safety_test.
459#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG)
460#define ABSL_INTERNAL_MSVC_2017_DBG_MODE
461#endif
462
463#endif // ABSL_BASE_CONFIG_H_
464