1018 lines
32 KiB
Plaintext
1018 lines
32 KiB
Plaintext
= Boost.Predef
|
||
:author: Rene Rivera
|
||
:toc: left
|
||
:toclevels: 3
|
||
:sectanchors:
|
||
:sectnums:
|
||
:nofooter:
|
||
:source-highlighter: pygments
|
||
:source-language: cpp
|
||
:caution-caption: ⚑
|
||
:important-caption: ‼
|
||
:note-caption: ℹ
|
||
:tip-caption: ☀
|
||
:warning-caption: ⚠
|
||
:CPP: C++
|
||
:predef_symbol: Symbol
|
||
:predef_version: Version
|
||
:predef_detection: pass:q[*detection*]
|
||
|
||
ifdef::backend-html5[]
|
||
++++
|
||
<style>
|
||
include::predef.css[]
|
||
</style>
|
||
++++
|
||
endif::[]
|
||
|
||
== Introduction
|
||
|
||
This library defines a set of compiler, architecture, operating system,
|
||
library, and other version numbers from the information it can gather of
|
||
C, {CPP}, Objective C, and Objective {CPP} predefined macros or those defined
|
||
in generally available headers. The idea for this library grew out of a
|
||
proposal to extend the Boost Config library to provide more, and consistent,
|
||
information than the feature definitions it supports. What follows is
|
||
an edited version of that brief proposal.
|
||
|
||
=== Proposal
|
||
|
||
The idea is to define a set of macros to identify compilers and
|
||
consistently represent their version. This includes:
|
||
|
||
* A unique BOOST_VERSION_NUMBER(major,minor,patch) macro to specify version
|
||
numbers (unfortunately, the name BOOST_VERSION is already taken to designate
|
||
the version number of boost itself).
|
||
* A compiler identification macro, suitable for use in `#if`/`#elif` directives,
|
||
for each of the supported compilers. All macros would be defined, regardless
|
||
of the compiler. The one macro corresponding to the compiler being used would
|
||
be defined, in terms of BOOST_VERSION_NUMBER, to carry the exact compiler
|
||
version. All other macros would expand to an expression evaluating to false
|
||
(for instance, the token 0) to indicate that the corresponding compiler is not
|
||
present.
|
||
* "Null values" could be set, for all macros, in
|
||
boost/config/select_compiler.hpp; then, for each compiler the corresponding
|
||
identification macro would be #undef and re-#defined in the corresponding
|
||
boost/compiler/(cc).hpp; however in the context of the Boost.Config
|
||
infrastructure using a "prefix" header (to be introduced) or
|
||
boost/config/suffix.hpp is a better solution.
|
||
|
||
=== Current Library
|
||
|
||
The current Predef library is now, both an independent library, and expanded
|
||
in scope. It includes detection and definition of architectures, compilers,
|
||
languages, libraries, operating systems, and endianness. The key benefits are:
|
||
|
||
* Version numbers that are always defined so that one doesn't have to guard
|
||
with `#ifdef`.
|
||
* Guard macros that can be used for `#ifdef` checks.
|
||
* All possible definitions are included with the single `#include <boost/predef.h>`
|
||
so that it's friendly to pre-compiled header usage.
|
||
* Specific definitions can be included, ex. `#include <boost/predef/os/windows.h>`
|
||
for single checks.
|
||
* Predefs can be directly used in both preprocessor and compiler expressions
|
||
for comparison to other similarly defined values.
|
||
* The headers are usable from multiple languages, that support the C preprocessor.
|
||
In particular {CPP}, C, Objective C, and Objective {CPP}.
|
||
|
||
=== Design choices
|
||
|
||
An important design choice concerns how to represent compiler versions by means
|
||
of a single integer number suitable for use in preprocessing directives. Let's
|
||
do some calculation. The "basic" signed type for preprocessing
|
||
constant-expressions is long in C90 (and {CPP}, as of 2006) and intmax_t in C99.
|
||
The type long shall at least be able to represent the number `+2 147 483 647`.
|
||
This means the most significant digit can only be 0, 1 or 2; and if we want all
|
||
decimal digits to be able to vary between 0 and 9, the largest range we can
|
||
consider is `[0, 999 999 999\`]. Distributing evenly, this means 3 decimal
|
||
digits for each version number part.
|
||
|
||
So we can:
|
||
|
||
. use an uneven distribution or
|
||
. use more bits (a larger type) or
|
||
. use 3/3/3 and have the particular compiler/platform/stdlib deal with setting
|
||
the numbers within the 3-digit range.
|
||
|
||
It appears relatively safe to go for the first option and set it at 2/2/5. That
|
||
covers CodeWarrior and others, which are up to and past 10 for the major number.
|
||
Some compilers use the build number in lieu of the patch one; five digits
|
||
(which is already reached by V{CPP} 8) seems a reasonable limit even in this case.
|
||
|
||
NOTE: A 2/2/6 scheme would allow for bigger patch/build numbers at the cost,
|
||
for instance, of limiting the major version number to 20 (or, with further
|
||
constraints, to 21).
|
||
|
||
It might reassure the reader that this decision is actually encoded in one place
|
||
in the code; the definition of `BOOST_VERSION_NUMBER`.
|
||
|
||
=== Future work
|
||
|
||
Even though the basics of this library are done, there is much work that can be
|
||
done:
|
||
|
||
* Right now we limit the detection of libraries to known built-in predefined
|
||
macros, and to guaranteed to exist system and library headers. It might be
|
||
interesting to add something like auto-configuration predefs. This way we can
|
||
add definitions for user specific libraries and features.
|
||
* Along with the above, it might be good to add some user control as to which
|
||
headers are included with the top-level header. Although in the current
|
||
form of the library this is less of an issue as one can include the
|
||
specific headers one needs.
|
||
* Additionally, even if there is no auto-configure style option.. It would be
|
||
good to add optionally included headers so that user can get consistent
|
||
version number definitions for libraries they use.
|
||
* And obviously there's lots of work to do in reformulating the existing
|
||
Boost libraries to use the Predef library.
|
||
* And there's the continuing work of adding definitions for present and
|
||
future compilers, platforms, architectures, languages, and libraries.
|
||
|
||
|
||
== Using the predefs
|
||
|
||
To use the automatically defined predefs one needs to only include the
|
||
single top-level header:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef.h>
|
||
----
|
||
|
||
This defines [*all] the version macros known to the library. For each
|
||
macro it will be defined to either a`_zero_`valued expression for when
|
||
the particular item is not detected, and to a`_positive_`value if it
|
||
is detected. The predef macros fall onto five categories each with
|
||
macros of a particular prefix:
|
||
|
||
* `BOOST_ARCH_` for system/CPU architecture one is compiling for.
|
||
* `BOOST_COMP_` for the compiler one is using.
|
||
* `BOOST_LANG_` for language standards one is compiling against.
|
||
* `BOOST_LIB_C_` and `BOOST_LIB_STD_` for the C and {CPP} standard library
|
||
in use.
|
||
* `BOOST_OS_` for the operating system we are compiling to.
|
||
* `BOOST_PLAT_` for platforms on top of operating system or compilers.
|
||
* `BOOST_ENDIAN_` for endianness of the os and architecture combination.
|
||
* `BOOST_HW_` for hardware specific features.
|
||
* `BOOST_HW_SIMD` for SIMD (Single Instruction Multiple Data) detection.
|
||
|
||
NOTE: The detected definitions are for the configuration one is targeting
|
||
during the compile. In particular in a cross-compile this means the target
|
||
system, and not the host system.
|
||
|
||
One uses the individual definitions to compare against specific versions
|
||
by comparing against the `BOOST_VERSION_NUMBER` macro. For example, to make
|
||
a choice based on the version of the GCC {CPP} compiler one would:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef.h>
|
||
#include <iostream>
|
||
|
||
int main()
|
||
{
|
||
if (BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0))
|
||
std::cout << "GCC compiler is at least version 4.0.0" << std::endl;
|
||
else
|
||
std::cout << "GCC compiler is at older than version 4.0.0, or not a GCC compiler" << std::endl;
|
||
return 0;
|
||
}
|
||
----
|
||
|
||
As you might notice above the `else` clause also covers the case where
|
||
the particular compiler is not detected. But one can make the test
|
||
also test for the detection. All predef definitions are defined
|
||
as a zero (0) expression when not detected. Hence one could use the
|
||
detection with a natural single condition. For example:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef.h>
|
||
#include <iostream>
|
||
|
||
int main()
|
||
{
|
||
if (BOOST_COMP_GNUC)
|
||
std::cout << "This is GNU GCC!" << std::endl;
|
||
else
|
||
std::cout << "Not GNU GCC." << std::endl;
|
||
return 0;
|
||
}
|
||
----
|
||
|
||
And since the predef's are preprocessor definitions the same is possible
|
||
from the preprocessor:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef.h>
|
||
#include <iostream>
|
||
|
||
#if BOOST_COMP_GNUC
|
||
#if BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0)
|
||
const char * the_compiler = "GNU GCC, of at least version 4."
|
||
#else
|
||
const char * the_compiler = "GNU GCC, less than version 4."
|
||
#endif
|
||
#else
|
||
const char * the_compiler = "Not GNU GCC."
|
||
#endif
|
||
|
||
int main()
|
||
{
|
||
std::cout << the_compiler << std::endl;
|
||
return 0;
|
||
}
|
||
----
|
||
|
||
In addition, for each version macro defined there is an
|
||
`*_AVAILABLE` macro defined only when the particular aspect is
|
||
detected. I.e. a definition equivalent to:
|
||
|
||
[source]
|
||
----
|
||
#if BOOST_PREDEF_ABC
|
||
#define BOOST_PREDEF_ABC_AVAILABLE
|
||
#endif
|
||
----
|
||
|
||
Also for each aspect there is a macro defined with a descriptive
|
||
name of what the detection is.
|
||
|
||
=== The `*_EMULATED` macros
|
||
|
||
Predef definitions are guaranteed to be uniquely detected within one category.
|
||
But there are contexts under which multiple underlying detections are possible.
|
||
The well known example of this is detection of GCC and MSVC compilers which are
|
||
commonly emulated by other compilers by defining the same base macros. To
|
||
account for this detection headers are allowed to define `*_EMULATED` predefs
|
||
when this situation is detected. The emulated predefs will be set to the
|
||
version number of the detection instead of the regular predef macro for that
|
||
detection. For example MSVC will set `BOOST_COMP_MSVC_EMULATED` but not set `BOOST_COMP_MSVC`, and it will also set `BOOST_COMP_MSVC_AVAILABLE`.
|
||
|
||
=== Using the `BOOST_VERSION_NUMBER` macro
|
||
|
||
All the predefs are defined to be a use of the `BOOST_VERSION_NUMBER` macro.
|
||
The macro takes individual major, minor, and patch value expressions:
|
||
|
||
[source]
|
||
----
|
||
#define BOOST_VERSION_NUMBER( major, minor, patch ) ...
|
||
----
|
||
|
||
The arguments are:
|
||
|
||
. Major version number, as a constant value expression in the range [0,99].
|
||
. Minor version number, as a constant value expression in the range [0,99].
|
||
. Patch-level version number, as a constant value expression in the
|
||
range [0,99999].
|
||
|
||
The ranges for each are "enforced" by the use of a modulo ("%"), i.e. truncation,
|
||
as opposed to a clamp. And hence this means that the limits are enforced only
|
||
enough to keep from having out-of-range problems. But not enough to prevent
|
||
other kinds of problems. Like exceeding the range and getting false detections,
|
||
or non-detections. It is up to the individual predefs to ensure correct
|
||
usage beyond the range guarantee.
|
||
|
||
The values for the arguments can be any preprocessor valid constant value expression.
|
||
Only constant value arithmetic is used in the definition of the `BOOST_VERSION_NUMBER`
|
||
macro and in any of the other predef macros. This means that any allowed base is
|
||
possible, i.e. binary, octal, decimal, and hexadecimal. For example:
|
||
|
||
[source]
|
||
----
|
||
#define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,0xA,015)
|
||
----
|
||
|
||
Is equivalent to:
|
||
|
||
[source]
|
||
----
|
||
#define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,10,13)
|
||
----
|
||
|
||
|
||
== Adding new predefs
|
||
|
||
We know that a library like this one will be an eternal work-in-progress. And
|
||
as such we expect, and look forward to, others contributing corrections and
|
||
additions to the predefs. With that in mind we need to keep a consistent way
|
||
of defining the new predefs. Hence all current, and future, predefs follow
|
||
the same structure and requirements.
|
||
|
||
=== Requirements of the header
|
||
|
||
All predefs need to follow a set of requirements:
|
||
|
||
* The headers must use the Boost Software License.
|
||
* The predef must, by default, be defined as `BOOST_VERSION_NUMBER_NOT_AVAILABLE`.
|
||
* The predef must be redefined to a non-zero value once detected.
|
||
* The predef must, by default, be defined to `BOOST_VERSION_NUMBER_AVAILABLE`
|
||
when the predef is detected.
|
||
* If possible, the predef will be defined as the version number detected.
|
||
* The predef must define `*_AVAILABLE` macros as needed.
|
||
* The predef must define a symbolic constant string name macro.
|
||
* The predef must declare itself, after being defined, for the testing
|
||
system.
|
||
* The predef must guarantee that it is the only one defined as detected
|
||
per category.
|
||
* But a predef can define `*_EMULATED` macros to indicate that it was
|
||
previously detected by another header and is being "emulated" by the
|
||
system. Note that the `*_AVAILABLE` macros must still be defined in this
|
||
situation.
|
||
|
||
And there are some extra guidelines that predef headers should follow:
|
||
|
||
* The detection should avoid including extra headers that might otherwise
|
||
not be included by default.
|
||
* If the detection must include a header, prefer guarding it within the
|
||
detection if possible.
|
||
* If the detection must include headers unconditionally, and has a choice
|
||
of headers to include, prefer the ones with the least impact. I.e.
|
||
include the one with the minimal set of definitions and other
|
||
dependencies.
|
||
|
||
=== Structure of the header
|
||
|
||
For general consistency it's suggested that new predef headers follow the
|
||
structure below, as current predef headers do. First we have the copyright
|
||
and license statement, followed by the include guard:
|
||
|
||
[source]
|
||
----
|
||
/*
|
||
Copyright Jane Doe YYYY
|
||
Distributed under the Boost Software License, Version 1.0.
|
||
(See accompanying file LICENSE_1_0.txt or copy at
|
||
http://www.boost.org/LICENSE_1_0.txt)
|
||
*/
|
||
|
||
#ifndef BOOST_PREDEF_category_tag_H
|
||
#define BOOST_PREDEF_category_tag_H
|
||
----
|
||
|
||
If the detection depends on the detection of another predef you should
|
||
include those headers here.
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef/CATEGORY_TAG/DEPENDENCY.h>
|
||
----
|
||
|
||
Depending on how you are defining the predef you will at minimum have
|
||
to include the `version_number.h` header. But you might also want to
|
||
include the `make.h` header for the version number decomposing utility
|
||
macros:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef/version_number.h>
|
||
#include <boost/predef/make.h>
|
||
----
|
||
|
||
The Predef library uses https://asciidoctor.org/[Asciidoctor] for documentation
|
||
and for the individual predefs to appear in the reference section we add
|
||
in-code documentation followed by the zero-value default definition of the
|
||
predef macro. We strongly recommend this particular placement of the
|
||
documentation and default definition because some development
|
||
environments automatically interpret this and provide in-line help
|
||
for the macro. In particular this works for the popular Eclipse IDE:
|
||
|
||
[source]
|
||
----
|
||
/* tag::reference[]
|
||
|
||
= `BOOST_category_tag`
|
||
|
||
Documentation about what is detected.
|
||
|
||
*/
|
||
|
||
#define BOOST_category_tag BOOST_VERSION_NUMBER_NOT_AVAILABLE
|
||
----
|
||
|
||
Next is the detection and definition of the particular predef. The
|
||
structure for this is to do a single overall check (`condition_a`) and
|
||
place further version detection inside this. The first action inside
|
||
the overall check is to "`#undef BOOST_category_tag`" which removes
|
||
the zero-value default. The rest is up to the you how to do the checks
|
||
for defining the version. But at minimum it must
|
||
"`#define BOOST_category_tag BOOST_VERSION_NUMBER_AVAILABLE`" as
|
||
the fallback to minimally indicate that the predef was detected:
|
||
|
||
[source]
|
||
----
|
||
#if (condition_a)
|
||
# undef BOOST_category_tag
|
||
# if (condition_b)
|
||
# define BOOST_category_tag BOOST_VERSION_NUMBER(major,minor,patch)
|
||
# else
|
||
# define BOOST_category_tag BOOST_VERSION_NUMBER_AVAILABLE
|
||
# endif
|
||
#endif
|
||
----
|
||
|
||
We also need to provide the `*_AVAILABLE` versions of the predef.
|
||
|
||
[source]
|
||
----
|
||
#if BOOST_category_tag
|
||
# define BOOST_category_tag_AVAILABLE
|
||
#endif
|
||
----
|
||
|
||
And for convenience we also want to provide a `*_NAME` macro:
|
||
|
||
[source]
|
||
----
|
||
#define BOOST_category_tag_NAME "Name"
|
||
----
|
||
|
||
We close out the include guard at this point. We do whis before the test
|
||
declaration as the testing system includes the headers multiple times
|
||
to generate the needed testing code.
|
||
|
||
[source]
|
||
----
|
||
#endif
|
||
----
|
||
|
||
The testing of the predef macros is automated to generate checks for all
|
||
the defined predefs, whether detected or not. To do this we need to
|
||
declare the predef to the test system. This declaration is empty for
|
||
regular use. And during the test programs they expand out specially
|
||
to create informational output:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef/detail/test.h>
|
||
BOOST_PREDEF_DECLARE_TEST(BOOST_category_tag,BOOST_category_tag_NAME)
|
||
----
|
||
|
||
=== Adding exclusive predefs
|
||
|
||
For headers of predefs that need to be mutually exclusive in the detection
|
||
we need to add checks and definitions to detect when the predef is
|
||
detected by multiple headers.
|
||
|
||
Internally compiler, operating system, and platforms define
|
||
`BOOST_PREDEF_DETAIL_COMP_DETECTED`, `BOOST_PREDEF_DEFAIL_OS_DETECTED`, and
|
||
`BOOST_PREDEF_DETAIL_PLAT_DETECTED` respectively when the predef is first
|
||
detected. This is used to guard against multiple definition of the detection
|
||
in later included headers. In those cases the detection would instead be
|
||
written as:
|
||
|
||
[source]
|
||
----
|
||
#if !BOOST_PREDEF_DETAIL_category_DETECTED && (condition_a)
|
||
# undef BOOST_category_tag
|
||
# if (condition_b)
|
||
# define BOOST_category_tag BOOST_VERSION_NUMBER(major,minor,patch)
|
||
# else
|
||
# define BOOST_category_tag BOOST_VERSION_NUMBER(0,0,1)
|
||
# endif
|
||
#endif
|
||
----
|
||
|
||
And we also include a header that defines the `*_DETECTED` macro when we have
|
||
the detection:
|
||
|
||
[source]
|
||
----
|
||
#if BOOST_category_tag
|
||
# define BOOST_category_tag_AVAILABLE
|
||
# include <boost/predef/detail/CATEGORY_detected.h>
|
||
#endif
|
||
----
|
||
|
||
Everything else about the header is the same as the basic detection header.
|
||
|
||
=== Adding an exclusive but emulated predef
|
||
|
||
Because compilers are frequently emulated by other compilers we both want
|
||
to have exclusive detection of the compiler and also provide information
|
||
that we detected the emulation of the compiler. To accomplish this we define
|
||
a local `*_DETECTION` macro for the compiler detection. And conditionally
|
||
define either the base compiler predef `BOOST_COMP_compiler` or the alternate
|
||
`BOOST_COMP_compiler_EMULATED` predef.
|
||
|
||
The initial detection would look like:
|
||
|
||
[source]
|
||
----
|
||
#if (condition_a)
|
||
# if (condition_b)
|
||
# define BOOST_COMP_tag_DETECTION BOOST_VERSION_NUMBER(major,minor,patch)
|
||
# else
|
||
# define BOOST_COMP_tag_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
|
||
# endif
|
||
#endif
|
||
----
|
||
|
||
And then we can conditionally define the base or emulated predefs:
|
||
|
||
[source]
|
||
----
|
||
#ifdef BOOST_COMP_tag_DETECTION
|
||
# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
|
||
# define BOOST_COMP_tag_EMULATED BOOST_COMP_tag_DETECTION
|
||
# else
|
||
# undef BOOST_COMP_tag
|
||
# define BOOST_COMP_tag BOOST_COMP_tag_DETECTION
|
||
# endif
|
||
# define BOOST_category_tag_AVAILABLE
|
||
# include <boost/predef/detail/comp_detected.h>
|
||
#endif
|
||
----
|
||
|
||
=== Using utility pattern macros
|
||
|
||
By including:
|
||
|
||
[source]
|
||
----
|
||
#include <boost/predef/make.h>
|
||
----
|
||
|
||
One will get a set of utility macros to decompose common version
|
||
macros as defined by compilers. For example the EDG compiler
|
||
uses a simple 3-digit version macro (M,N,P). It can be decomposed
|
||
and defined as:
|
||
|
||
[source]
|
||
----
|
||
#define BOOST_COMP_EDG BOOST_PREDEF_MAKE_N_N_N(__EDG_VERSION__)
|
||
----
|
||
|
||
The decomposition macros are split into three types: decimal
|
||
decomposition, hexadecimal decomposition, and date decomposition.
|
||
They follow the format of using "N" for decimal, "F" for hexadecimal,
|
||
and "Y", "M", "D" for dates.
|
||
|
||
|
||
|
||
== Reference
|
||
|
||
=== `BOOST_ARCH` architecture macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/architecture/alpha.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/arm.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/blackfin.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/convex.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/e2k.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/ia64.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/m68k.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/mips.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/parisc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/ppc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/ptx.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/pyramid.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/riscv.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/rs6k.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/sparc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/superh.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/sys370.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/sys390.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/x86.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/z.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/x86/32.h[tag=reference]
|
||
|
||
include::../include/boost/predef/architecture/x86/64.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_COMP` compiler macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/compiler/borland.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/clang.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/comeau.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/compaq.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/diab.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/digitalmars.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/dignus.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/edg.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/ekopath.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/gcc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/gcc_xml.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/greenhills.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/hp_acc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/iar.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/ibm.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/intel.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/kai.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/llvm.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/metaware.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/metrowerks.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/microtec.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/mpw.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/nvcc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/palm.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/pgi.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/sgi_mipspro.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/sunpro.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/tendra.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/visualc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/compiler/watcom.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_LANG` language standards macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/language/cuda.h[tag=reference]
|
||
|
||
include::../include/boost/predef/language/objc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/language/stdc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/language/stdcpp.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_LIB` library macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/library/c/cloudabi.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/c/gnu.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/c/uc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/c/vms.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/c/zos.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/cxx.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/dinkumware.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/libcomo.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/modena.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/msl.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/roguewave.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/sgi.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/stdcpp3.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/stlport.h[tag=reference]
|
||
|
||
include::../include/boost/predef/library/std/vacpp.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_OS` operating system macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/os/aix.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/amigaos.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/beos.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/cygwin.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/haiku.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/hpux.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/ios.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/irix.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/linux.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/macos.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/os400.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/qnxnto.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/solaris.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/unix.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/vms.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/windows.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd/bsdi.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd/dragonfly.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd/free.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd/net.h[tag=reference]
|
||
|
||
include::../include/boost/predef/os/bsd/open.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_PLAT` platform macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/platform/android.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/cloudabi.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/ios.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/mingw.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/mingw32.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/mingw64.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_desktop.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_phone.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_runtime.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_server.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_store.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_system.h[tag=reference]
|
||
|
||
include::../include/boost/predef/platform/windows_uwp.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== `BOOST_HW` hardware macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/hardware/simd.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/arm.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/arm/versions.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/ppc.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/ppc/versions.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/x86.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/x86/versions.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/x86_amd.h[tag=reference]
|
||
|
||
include::../include/boost/predef/hardware/simd/x86_amd/versions.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== Other macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/other/endian.h[tag=reference]
|
||
|
||
include::../include/boost/predef/other/wordsize.h[tag=reference]
|
||
|
||
include::../include/boost/predef/other/workaround.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
=== Version definition macros
|
||
|
||
:leveloffset: +3
|
||
|
||
include::../include/boost/predef/version_number.h[tag=reference]
|
||
|
||
include::../include/boost/predef/make.h[tag=reference]
|
||
|
||
:leveloffset: -3
|
||
|
||
== Check Utilities
|
||
|
||
The `predef_check` utility provides a facility for building a
|
||
program that will check a given set of expressions against
|
||
the definitions it detected when it was built.
|
||
|
||
=== `predef_check` programs
|
||
|
||
Even though there is only one `predef_check` program, there
|
||
are variations for each of the languages that are detected
|
||
by Predef to match the convention for sources files. For all
|
||
of them one invokes with a list of expression arguments. The
|
||
expressions are evaluated within the context of the particular
|
||
`predef_check` program and if they all are true zero (0) is returned.
|
||
Otherwise the index of the first false expression is returned.
|
||
|
||
The expression syntax is simple:
|
||
|
||
[source,jam]
|
||
----
|
||
predef-definition [ relational-operator version-value ]
|
||
----
|
||
|
||
_predef-definition_ can be any of the Predef definitions. For
|
||
example `BOOST_COMP_GCC`.
|
||
|
||
_relational-operator_ can be any of: `>`, `<`, `>=`, `<=`,
|
||
`==` and `!=`.
|
||
|
||
_version-number_ can be a full or partial version triplet value.
|
||
If it's a partial version triple it is completed with zeros. That
|
||
is `x.y` is equivalent to `x.y.0` and `x` is equivalent to
|
||
`x.0.0`.
|
||
|
||
The _relations-operator_ and _version-number_ can be omitted. In
|
||
which case it is equivalent to:
|
||
|
||
[source,jam]
|
||
----
|
||
predef-definition > 0.0.0
|
||
----
|
||
|
||
=== Using with Boost.Build
|
||
|
||
You can use the `predef_check` programs directly from Boost Build
|
||
to configure target requirements. This is useful for controlling
|
||
what gets built as part of your project based on the detailed
|
||
version information available in Predef. The basic use is simple:
|
||
|
||
[source,jam]
|
||
----
|
||
import path-to-predef-src/tools/check/predef
|
||
: check require
|
||
: predef-check predef-require ;
|
||
|
||
exe my_windows_program : windows_source.cpp
|
||
: [ predef-require "BOOST_OS_WINDOWS" ] ;
|
||
----
|
||
|
||
That simple use case will skip building the `my_windows_program`
|
||
unless one is building for Windows. Like the direct `predef_check`
|
||
you can pass multiple expressions using relational comparisons.
|
||
For example:
|
||
|
||
[source,jam]
|
||
----
|
||
import path-to-predef-src/tools/check/predef
|
||
: check require
|
||
: predef-check predef-require ;
|
||
|
||
lib my_special_lib : source.cpp
|
||
: [ predef-require "BOOST_OS_WINDOWS != 0" "BOOST_OS_VMS != 0"] ;
|
||
----
|
||
|
||
And in that case the `my_special_lib` is built only when the OS is
|
||
not Windows or VMS. The `requires` rule is a special case of the
|
||
`check` rule. And is defined in terms of it:
|
||
|
||
[source,jam]
|
||
----
|
||
rule require ( expressions + : language ? )
|
||
{
|
||
return [ check $(expressions) : $(language) : : <build>no ] ;
|
||
}
|
||
----
|
||
|
||
The expression can also use explicit "and", "or" logical operators
|
||
to for more complex checks:
|
||
|
||
|
||
[source,jam]
|
||
----
|
||
import path-to-predef-src/tools/check/predef
|
||
: check require
|
||
: predef-check predef-require ;
|
||
|
||
lib my_special_lib : source.cpp
|
||
: [ predef-require "BOOST_OS_WINDOWS" or "BOOST_OS_VMS"] ;
|
||
----
|
||
|
||
You can use the `check` rule for more control and to implement
|
||
something other than control of what gets built. The definition
|
||
for the `check` rule is:
|
||
|
||
[source,jam]
|
||
----
|
||
rule check ( expressions + : language ? : true-properties * : false-properties * )
|
||
----
|
||
|
||
When invoked as a requirement of a Boost Build target this rule
|
||
will add the `true-properties` to the target if all the `expressions`
|
||
evaluate to true. Otherwise the `false-properties` get added as
|
||
requirements. For example you could use it to enable or disable
|
||
features in your programs:
|
||
|
||
[source,jam]
|
||
----
|
||
import path-to-predef-src/tools/check/predef
|
||
: check require
|
||
: predef-check predef-require ;
|
||
|
||
exe my_special_exe : source.cpp
|
||
: [ predef-check "BOOST_OS_WINDOWS == 0"
|
||
: : <define>ENABLE_WMF=0
|
||
: <define>ENABLE_WMF=1 ] ;
|
||
----
|
||
|
||
For both `check` and `require` the `language` argument controls
|
||
which variant of the `predef_check` program is used to check the
|
||
expressions. It defaults to "c++", but can be any of: "c", "cpp",
|
||
"objc", and "objcpp".
|
||
|
||
|
||
:leveloffset: +1
|
||
|
||
include::history.adoc[]
|
||
|
||
include::todo.adoc[]
|
||
|
||
:leveloffset: -1
|
||
|
||
== Acknowledgements
|
||
|
||
The comprehensiveness of this library would not be
|
||
possible without the existence of the indispensable
|
||
resource that is the
|
||
http://sourceforge.net/p/predef/[Pre-defined C/{CPP} Compiler Macros]
|
||
Project. It was, and continues to be, the primary source
|
||
of the definitions that make up this library. Thanks
|
||
to Bjorn Reese and all the volunteers that make that
|
||
resource possible.
|
||
|
||
This library would be an incoherent mess if it weren't for
|
||
Boost community that provided invaluable feedback for the
|
||
eight years that it took to polish into a useable form.
|
||
In particular I would like to thank: Mathias Gaunard,
|
||
Robert Stewart, Joël Lamotte, Lars Viklund, Nathan Ridge,
|
||
Artyom Beilis, Joshua Boyce, Gottlob Frege, Thomas Heller,
|
||
Edward Diener, Dave Abrahams, Iain Denniston, Dan Price,
|
||
Ioannis Papadopoulos, and Robert Ramey. And thanks to
|
||
Joel Falcou for managing the review of this library.
|
||
|
||
[colophon]
|
||
== Colophon
|
||
|
||
Distributed under the Boost Software License, Version 1.0.
|
||
(See accompanying file LICENSE_1_0.txt or copy at
|
||
https://www.boost.org/LICENSE_1_0.txt)
|
||
|
||
Copyright 2005-2020 Rene Rivera; Copyright 2015 Charly Chevalier; Copyright 2015 Joel Falcou |