blob: 39cf7b23a71515e4ff644bc485f9308dcb4f3e38 [file] [log] [blame]
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Module Overview: Starboard Configuration module
//
// Provides a description of the current platform in lurid detail so that
// common code never needs to actually know what the current operating system
// and architecture are.
//
// It is both very pragmatic and canonical in that if any application code
// finds itself needing to make a platform decision, it should always define
// a Starboard Configuration feature instead. This implies the continued
// existence of very narrowly-defined configuration features, but it retains
// porting control in Starboard.
#ifndef STARBOARD_CONFIGURATION_H_
#define STARBOARD_CONFIGURATION_H_
#if !defined(STARBOARD)
#error "You must define STARBOARD in Starboard builds."
#endif
// --- Common Defines --------------------------------------------------------
// The minimum API version allowed by this version of the Starboard headers,
// inclusive.
#define SB_MINIMUM_API_VERSION 13
// The maximum API version allowed by this version of the Starboard headers,
// inclusive. The API version is not stable and is open for changes.
#define SB_MAXIMUM_API_VERSION 16
// --- Common Detected Features ----------------------------------------------
#if defined(__GNUC__)
#define SB_IS_COMPILER_GCC 1
#elif defined(_MSC_VER)
#define SB_IS_COMPILER_MSVC 1
#endif
// --- Common Helper Macros --------------------------------------------------
// Determines a compile-time capability of the system.
#define SB_CAN(SB_FEATURE) \
((defined SB_CAN_##SB_FEATURE) && SB_CAN_##SB_FEATURE)
// Determines at compile-time whether this platform has a standard feature or
// header available.
#define SB_HAS(SB_FEATURE) \
((defined SB_HAS_##SB_FEATURE) && SB_HAS_##SB_FEATURE)
// Determines at compile-time an inherent aspect of this platform.
#define SB_IS(SB_FEATURE) ((defined SB_IS_##SB_FEATURE) && SB_IS_##SB_FEATURE)
// Determines at compile-time whether this platform has a quirk.
#define SB_HAS_QUIRK(SB_FEATURE) \
((defined SB_HAS_QUIRK_##SB_FEATURE) && SB_HAS_QUIRK_##SB_FEATURE)
// Determines at compile-time the size of a data type, or 0 if the data type
// that was specified was invalid.
#define SB_SIZE_OF(DATATYPE) \
((defined SB_SIZE_OF_##DATATYPE) ? (SB_SIZE_OF_##DATATYPE) : (0))
// A constant expression that evaluates to the size_t size of a statically-sized
// array.
#define SB_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
// A constant expression that evaluates to the int size of a statically-sized
// array.
#if defined(__cplusplus)
#define SB_ARRAY_SIZE_INT(array) static_cast<int>(SB_ARRAY_SIZE(array))
#else
#define SB_ARRAY_SIZE_INT(array) \
((int)(SB_ARRAY_SIZE(array))) // NOLINT(readability/casting)
#endif
// Will cause a compiler error with |msg| if |expr| is false. |msg| must be a
// valid identifier, and must be a unique type in the scope of the declaration.
#if defined(__cplusplus)
extern "C++" {
namespace starboard {
template <bool>
struct CompileAssert {};
} // namespace starboard
} // extern "C++"
#define SB_COMPILE_ASSERT(expr, msg) \
typedef ::starboard::CompileAssert<( \
bool(expr))> /* NOLINT(readability/casting) */ \
msg[bool(expr) ? 1 : -1] // NOLINT(readability/casting)
#else
#define SB_COMPILE_ASSERT(expr, msg) \
extern char _COMPILE_ASSERT_##msg[(expr) ? 1 : -1]
#endif
// Standard CPP trick to stringify an evaluated macro definition.
#define SB_STRINGIFY(x) SB_STRINGIFY2(x)
#define SB_STRINGIFY2(x) #x
// An enumeration of values for the kSbPreferredByteOrder configuration
// variable. Setting this up properly means avoiding slow color swizzles when
// passing pixel data from one library to another. Note that these definitions
// are in byte-order and so are endianness-independent.
#define SB_PREFERRED_RGBA_BYTE_ORDER_RGBA 1
#define SB_PREFERRED_RGBA_BYTE_ORDER_BGRA 2
#define SB_PREFERRED_RGBA_BYTE_ORDER_ARGB 3
// --- Platform Configuration ------------------------------------------------
// Include the platform-specific configuration. This macro is set by GN in
// starboard/build/config/BUILD.gn and passed in on the command line for all
// targets and all configurations.
#include STARBOARD_CONFIGURATION_INCLUDE
// --- Overridable Helper Macros ---------------------------------------------
// The following macros can be overridden in STARBOARD_CONFIGURATION_INCLUDE
// Makes a pointer-typed parameter restricted so that the compiler can make
// certain optimizations because it knows the pointers are unique.
#if !defined(SB_RESTRICT)
#if defined(__cplusplus)
#if SB_IS(COMPILER_MSVC)
#define SB_RESTRICT __restrict
#elif SB_IS(COMPILER_GCC)
#define SB_RESTRICT __restrict__
#else // COMPILER
#define SB_RESTRICT
#endif // COMPILER
#else // __cplusplus
#define SB_RESTRICT __restrict
#endif // __cplusplus
#endif // SB_RESTRICT
// Tells the compiler a function is using a printf-style format string.
// |format_param| is the one-based index of the format string parameter;
// |dots_param| is the one-based index of the "..." parameter.
// For v*printf functions (which take a va_list), pass 0 for dots_param.
// (This is undocumented but matches what the system C headers do.)
// (Partially taken from base/compiler_specific.h)
#if !defined(SB_PRINTF_FORMAT)
#if SB_IS(COMPILER_GCC)
#define SB_PRINTF_FORMAT(format_param, dots_param) \
__attribute__((format(printf, format_param, dots_param)))
#else
#define SB_PRINTF_FORMAT(format_param, dots_param)
#endif
#endif // SB_PRINTF_FORMAT
// Trivially references a parameter that is otherwise unreferenced, preventing a
// compiler warning on some platforms.
#if !defined(SB_UNREFERENCED_PARAMETER)
#if SB_IS(COMPILER_MSVC)
#define SB_UNREFERENCED_PARAMETER(x) (x)
#else
#define SB_UNREFERENCED_PARAMETER(x) \
do { \
(void)(x); \
} while (0)
#endif
#endif // SB_UNREFERENCED_PARAMETER
// Causes the annotated (at the end) function to generate a warning if the
// result is not accessed.
#if !defined(SB_WARN_UNUSED_RESULT)
#if defined(COMPILER_GCC)
#define SB_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define SB_WARN_UNUSED_RESULT
#endif // COMPILER_GCC
#endif // SB_WARN_UNUSED_RESULT
// Declare numeric literals of signed 64-bit type.
#if !defined(SB_INT64_C)
#if defined(_MSC_VER)
#define SB_INT64_C(x) x##I64
#else // defined(_MSC_VER)
#define SB_INT64_C(x) x##LL
#endif // defined(_MSC_VER)
#endif // SB_INT64_C
// Declare numeric literals of unsigned 64-bit type.
#if !defined(SB_UINT64_C)
#if defined(_MSC_VER)
#define SB_UINT64_C(x) x##UI64
#else // defined(_MSC_VER)
#define SB_UINT64_C(x) x##ULL
#endif // defined(_MSC_VER)
#endif // SB_INT64_C
// Macro for hinting that an expression is likely to be true.
#if !defined(SB_LIKELY)
#if SB_IS(COMPILER_GCC)
#define SB_LIKELY(x) __builtin_expect(!!(x), 1)
#elif SB_IS(COMPILER_MSVC)
#define SB_LIKELY(x) (x)
#else
#define SB_LIKELY(x) (x)
#endif // SB_IS(COMPILER_MSVC)
#endif // !defined(SB_LIKELY)
// Macro for hinting that an expression is likely to be false.
#if !defined(SB_UNLIKELY)
#if SB_IS(COMPILER_GCC)
#define SB_UNLIKELY(x) __builtin_expect(!!(x), 0)
#elif SB_IS(COMPILER_MSVC)
#define SB_UNLIKELY(x) (x)
#else
#define SB_UNLIKELY(x) (x)
#endif // SB_IS(COMPILER_MSVC)
#endif // !defined(SB_UNLIKELY)
// SB_DEPRECATED(int Foo(int bar));
// Annotates the function as deprecated, which will trigger a compiler
// warning when referenced.
#if !defined(SB_DEPRECATED)
#if SB_IS(COMPILER_GCC)
#define SB_DEPRECATED(FUNC) FUNC __attribute__((deprecated))
#elif SB_IS(COMPILER_MSVC)
#define SB_DEPRECATED(FUNC) __declspec(deprecated) FUNC
#else
// Empty definition for other compilers.
#define SB_DEPRECATED(FUNC) FUNC
#endif
#endif // SB_DEPRECATED
// SB_DEPRECATED_EXTERNAL(...) annotates the function as deprecated for
// external clients, but not deprecated for starboard.
#if defined(STARBOARD_IMPLEMENTATION)
#define SB_DEPRECATED_EXTERNAL(FUNC) FUNC
#else
#define SB_DEPRECATED_EXTERNAL(FUNC) SB_DEPRECATED(FUNC)
#endif
// Macro to annotate a function as noreturn, which signals to the compiler
// that the function cannot return.
#if !defined(SB_NORETURN)
#if SB_IS(COMPILER_GCC)
#define SB_NORETURN __attribute__((__noreturn__))
#elif SB_IS(COMPILER_MSVC)
#define SB_NORETURN __declspec(noreturn)
#else
// Empty definition for other compilers.
#define SB_NORETURN
#endif
#endif // SB_NORETURN
// Specifies the alignment for a class, struct, union, enum, class/struct field,
// or stack variable.
#if !defined(SB_ALIGNAS)
#if SB_IS(COMPILER_GCC)
#define SB_ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#elif SB_IS(COMPILER_MSVC)
#define SB_ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
#else
// Fallback to the C++11 form.
#define SB_ALIGNAS(byte_alignment) alignas(byte_alignment)
#endif
#endif // !defined(SB_ALIGNAS)
// Returns the alignment required for any instance of the type indicated by
// |type|.
#if !defined(SB_ALIGNOF)
#if SB_IS(COMPILER_GCC)
#define SB_ALIGNOF(type) __alignof__(type)
#elif SB_IS(COMPILER_MSVC)
#define SB_ALIGNOF(type) (sizeof(type) - sizeof(type) + __alignof(type))
#else
// Fallback to the C++11 form.
#define SB_ALIGNOF(type) alignof(type)
#endif
#endif // !defined(SB_ALIGNOF)
// --- Configuration Audits --------------------------------------------------
#if !defined(SB_API_VERSION)
#error "SB_API_VERSION was not defined by your platform."
#endif
#if SB_API_VERSION > SB_MAXIMUM_API_VERSION
#error "Your platform's SB_API_VERSION > SB_MAXIMUM_API_VERSION."
#endif
#if SB_API_VERSION < SB_MINIMUM_API_VERSION
#error "Your platform's SB_API_VERSION < SB_MINIMUM_API_VERSION."
#endif
#if !SB_IS(ARCH_ARM) && !SB_IS(ARCH_ARM64) && !SB_IS(ARCH_X86) && \
!SB_IS(ARCH_X64)
#error "Your platform doesn't define a known architecture."
#endif
#if SB_IS(32_BIT) == SB_IS(64_BIT)
#error "Your platform must be exactly one of { 32-bit, 64-bit }."
#endif
#if !SB_IS(BIG_ENDIAN) && !SB_IS(LITTLE_ENDIAN) || \
(SB_IS(BIG_ENDIAN) == SB_IS(LITTLE_ENDIAN))
#error "Your platform's endianness must be defined as big or little."
#endif
#if (SB_SIZE_OF(POINTER) != 4) && (SB_SIZE_OF(POINTER) != 8)
#error "Your platform's pointer sizes must be either 32 bit or 64 bit."
#endif
#if (SB_SIZE_OF(LONG) != 4) && (SB_SIZE_OF(LONG) != 8)
#error "Your platform's long size must be either 32 bit or 64 bit."
#endif
#if SB_IS(WCHAR_T_UTF16) == SB_IS(WCHAR_T_UTF32)
#error "You must define either SB_IS_WCHAR_T_UTF16 or SB_IS_WCHAR_T_UTF32."
#endif
#if defined(SB_IS_WCHAR_T_SIGNED) && defined(SB_IS_WCHAR_T_UNSIGNED)
#error "You can't define SB_IS_WCHAR_T_SIGNED and SB_IS_WCHAR_T_UNSIGNED."
#endif
// SB_C_FORCE_INLINE annotation for forcing a C function to be inlined.
#if SB_API_VERSION < 16
#if !defined(SB_C_FORCE_INLINE)
#error "Your platform must define SB_C_FORCE_INLINE."
#endif
#else // SB_API_VERSION < 16
#if defined(SB_C_FORCE_INLINE)
#error "Your platform must not define SB_C_FORCE_INLINE"
#else // defined(SB_C_FORCE_INLINE)
#if SB_IS(COMPILER_GCC)
#define SB_C_FORCE_INLINE inline __attribute__((always_inline))
#elif SB_IS(COMPILER_MSVC)
#define SB_C_FORCE_INLINE __forceinline
#else // Fallback to standard keyword with no enforcing
#define SB_C_FORCE_INLINE inline
#endif
#endif // defined(SB_C_FORCE_INLINE)
#endif // SB_API_VERSION < 16
#if SB_API_VERSION < 16
#if !defined(SB_C_INLINE)
#error "Your platform must define SB_C_INLINE."
#endif
#else
#if defined(SB_C_INLINE)
#error "Your platform should not define SB_C_INLINE, it is deprecated."
#else
#define SB_C_INLINE inline
#endif
#endif
// SB_EXPORT_PLATFORM annotates symbols as exported from shared libraries.
#if SB_API_VERSION < 16
#if !defined(SB_EXPORT_PLATFORM)
#error "Your platform must define SB_EXPORT_PLATFORM."
#endif
#else // SB_API_VERSION >= 16
#if !defined(SB_EXPORT_PLATFORM) // auto-configure
#if SB_IS(COMPILER_GCC)
#define SB_EXPORT_PLATFORM __attribute__((visibility("default")))
#elif SB_IS(COMPILER_MSVC)
#define SB_EXPORT_PLATFORM __declspec(dllexport)
#else // Fallback to standard keyword with no enforcing
#error "Could not determine compiler, you must define SB_EXPORT_PLATFORM."
#endif
#endif // !defined(SB_EXPORT_PLATFORM)
#endif // SB_API_VERSION >= 16
// SB_IMPORT_PLATFORM annotates symbols as imported from shared libraries.
#if SB_API_VERSION < 16
#if !defined(SB_IMPORT_PLATFORM)
#error "Your platform must define SB_IMPORT_PLATFORM."
#endif
#else // SB_API_VERSION >= 16
#if !defined(SB_IMPORT_PLATFORM) // auto-configure
#if SB_IS(COMPILER_GCC)
#define SB_IMPORT_PLATFORM
#elif SB_IS(COMPILER_MSVC)
#define SB_IMPORT_PLATFORM __declspec(dllimport)
#else // Fallback to standard keyword with no enforcing
#error "Could not determine compiler, you must define SB_IMPORT_PLATFORM."
#endif
#endif // !defined(SB_IMPORT_PLATFORM)
#endif // SB_API_VERSION >= 16
// --- Derived Configuration -------------------------------------------------
// Whether the current platform has 64-bit atomic operations.
#if SB_IS(64_BIT)
#define SB_HAS_64_BIT_ATOMICS 1
#else
#define SB_HAS_64_BIT_ATOMICS 0
#endif
// Whether we use __PRETTY_FUNCTION__ or __FUNCTION__ for logging.
#if SB_IS(COMPILER_GCC)
#define SB_FUNCTION __PRETTY_FUNCTION__
#else
#define SB_FUNCTION __FUNCTION__
#endif
// --- Deprecated Feature Macros -----------------------------------------------
// Deprecated feature macros are no longer referenced by application code, and
// will be removed in a later Starboard API version. Any Starboard
// implementation that supports any of these macros should be modified to no
// longer rely on them, and operate with the assumption that their values are
// always 1.
#endif // STARBOARD_CONFIGURATION_H_