predef.qbk 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. [article Boost.Predef
  2. [quickbook 1.7]
  3. [version 1.10]
  4. [authors [Rivera, Rene]]
  5. [copyright 2005-2019 Rene Rivera]
  6. [copyright 2015 Charly Chevalier]
  7. [copyright 2015 Joel Falcou]
  8. [purpose Identification and specification of predefined macros.]
  9. [license
  10. Distributed under the Boost Software License, Version 1.0.
  11. (See accompanying file LICENSE_1_0.txt or copy at
  12. [@http://www.boost.org/LICENSE_1_0.txt])
  13. ]
  14. [source-mode c++]
  15. [category miscellaneous]
  16. [id predef]
  17. [dirname predef]
  18. ]
  19. [section Introduction]
  20. This library defines a set of compiler, architecture, operating system,
  21. library, and other version numbers from the information it can gather of
  22. C, C++, Objective C, and Objective C++ predefined macros or those defined
  23. in generally available headers. The idea for this library grew out of a
  24. proposal to extend the Boost Config library to provide more, and consistent,
  25. information than the feature definitions it supports. What follows is
  26. an edited version of that brief proposal.
  27. [heading Proposal]
  28. The idea is to define a set of macros to identify compilers and
  29. consistently represent their version. This includes:
  30. * A unique BOOST_VERSION_NUMBER(major,minor,patch) macro to specify version
  31. numbers (unfortunately, the name BOOST_VERSION is already taken to designate
  32. the version number of boost itself).
  33. * A compiler identification macro, suitable for use in `#if`/`#elif` directives,
  34. for each of the supported compilers. All macros would be defined, regardless
  35. of the compiler. The one macro corresponding to the compiler being used would
  36. be defined, in terms of BOOST_VERSION_NUMBER, to carry the exact compiler
  37. version. All other macros would expand to an expression evaluating to false
  38. (for instance, the token 0) to indicate that the corresponding compiler is not
  39. present.
  40. * "Null values" could be set, for all macros, in
  41. boost/config/select_compiler.hpp; then, for each compiler the corresponding
  42. identification macro would be #undef and re-#defined in the corresponding
  43. boost/compiler/(cc).hpp; however in the context of the Boost.Config
  44. infrastructure using a "prefix" header (to be introduced) or
  45. boost/config/suffix.hpp is a better solution.
  46. [heading Current Library]
  47. The current Predef library is now, both an independent library, and expanded
  48. in scope. It includes detection and definition of architectures, compilers,
  49. languages, libraries, operating systems, and endianness. The key benefits are:
  50. * Version numbers that are always defined so that one doesn't have to guard
  51. with `#ifdef`.
  52. * Guard macros that can be used for `#ifdef` checks.
  53. * All possible definitions are included with the single `#include <boost/predef.h>`
  54. so that it's friendly to precompiled header usage.
  55. * Specific definitions can be included, ex. `#include <boost/predef/os/windows.h>`
  56. for single checks.
  57. * Predefs can be directly used in both preprocessor and compiler expressions
  58. for comparison to other similarly defined values.
  59. * The headers are usable from multiple languages, that support the C preprocessor.
  60. In particular C++, C, Objective C, and Objective C++.
  61. [heading Design choices]
  62. An important design choice concerns how to represent compiler versions by means
  63. of a single integer number suitable for use in preprocessing directives. Let's
  64. do some calculation. The "basic" signed type for preprocessing
  65. constant-expressions is long in C90 (and C++, as of 2006) and intmax_t in C99.
  66. The type long shall at least be able to represent the number [^+2 147 483 647].
  67. This means the most significant digit can only be 0, 1 or 2; and if we want all
  68. decimal digits to be able to vary between 0 and 9, the largest range we can
  69. consider is [^\[0, 999 999 999\]]. Distributing evenly, this means 3 decimal
  70. digits for each version number part.
  71. So we can:
  72. # use an uneven distribution or
  73. # use more bits (a larger type) or
  74. # use 3/3/3 and have the particular compiler/platform/stdlib deal with setting
  75. the numbers within the 3-digit range.
  76. It appears relatively safe to go for the first option and set it at 2/2/5. That
  77. covers CodeWarrior and others, which are up to and past 10 for the major number.
  78. Some compilers use the build number in lieu of the patch one; five digits
  79. (which is already reached by VC++ 8) seems a reasonable limit even in this case.
  80. [note A 2/2/6 scheme would allow for bigger patch/build numbers at the cost,
  81. for instance, of limiting the major version number to 20 (or, with further
  82. constraints, to 21).]
  83. It might reassure the reader that this decision is actually encoded in one place
  84. in the code; the definition of `BOOST_VERSION_NUMBER`.
  85. [heading Future work]
  86. Even though the basics of this library are done, there is much work that can be
  87. done:
  88. * Right now we limit the detection of libraries to known built-in predefined
  89. macros, and to guaranteed to exist system and library headers. It might be
  90. interesting to add something like auto-configuration predefs. This way we can
  91. add definitions for user specific libraries and features.
  92. * Along with the above, it might be good to add some user control as to which
  93. headers are included with the top-level header. Although in the current
  94. form of the library this is less of an issue as one can include the
  95. specific headers one needs.
  96. * Additionally, even if there is no auto-configure style option.. It would be
  97. good to add optionally included headers so that user can get consistent
  98. version number definitions for libraries they use.
  99. * And obviously there's lots of work to do in reformulating the existing
  100. Boost libraries to use the Predef library.
  101. * And there's the continuing work of adding definitions for present and
  102. future compilers, platforms, architectures, languages, and libraries.
  103. [endsect] [/Introduction]
  104. [section Using the predefs]
  105. To use the automatically defined predefs one needs to only include the
  106. single top-level header:
  107. ``
  108. #include <boost/predef.h>
  109. ``
  110. This defines [*all] the version macros known to the library. For each
  111. macro it will be defined to either a /zero/ valued expression for when
  112. the particular item is not detected, and to a /positive/ value if it
  113. is detected. The predef macros fall onto five categories each with
  114. macros of a particular prefix:
  115. * `BOOST_ARCH_`for system/CPU architecture one is compiling for.
  116. * `BOOST_COMP_` for the compiler one is using.
  117. * `BOOST_LANG_` for language standards one is compiling against.
  118. * `BOOST_LIB_C_` and `BOOST_LIB_STD_` for the C and C++ standard library
  119. in use.
  120. * `BOOST_OS_` for the operating system we are compiling to.
  121. * `BOOST_PLAT_` for platforms on top of operating system or compilers.
  122. * `BOOST_ENDIAN_` for endianness of the os and architecture combination.
  123. * `BOOST_HW_` for hardware specific features.
  124. * `BOOST_HW_SIMD` for SIMD (Single Instruction Multiple Data) detection.
  125. [note The detected definitions are for the configuration one is targeting
  126. during the compile. In particular in a cross-compile this means the target
  127. system, and not the host system.]
  128. One uses the individual definitions to compare against specific versions
  129. by comparing against the `BOOST_VERSION_NUMBER` macro. For example, to make
  130. a choice based on the version of the GCC C++ compiler one would:
  131. ``
  132. #include <boost/predef.h>
  133. #include <iostream>
  134. int main()
  135. {
  136. if (BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0))
  137. std::cout << "GCC compiler is at least version 4.0.0" << std::endl;
  138. else
  139. std::cout << "GCC compiler is at older than version 4.0.0, or not a GCC compiler" << std::endl;
  140. return 0;
  141. }
  142. ``
  143. As you might notice above the `else` clause also covers the case where
  144. the particular compiler is not detected. But one can make the test
  145. also test for the detection. All predef definitions are defined
  146. as a zero (0) expression when not detected. Hence one could use the
  147. detection with a natural single condition. For example:
  148. ``
  149. #include <boost/predef.h>
  150. #include <iostream>
  151. int main()
  152. {
  153. if (BOOST_COMP_GNUC)
  154. std::cout << "This is GNU GCC!" << std::endl;
  155. else
  156. std::cout << "Not GNU GCC." << std::endl;
  157. return 0;
  158. }
  159. ``
  160. And since the predef's are preprocessor definitions the same is possible
  161. from the preprocessor:
  162. ``
  163. #include <boost/predef.h>
  164. #include <iostream>
  165. #if BOOST_COMP_GNUC
  166. #if BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0)
  167. const char * the_compiler = "GNU GCC, of at least version 4."
  168. #else
  169. const char * the_compiler = "GNU GCC, less than version 4."
  170. #endif
  171. #else
  172. const char * the_compiler = "Not GNU GCC."
  173. #endif
  174. int main()
  175. {
  176. std::cout << the_compiler << std::endl;
  177. return 0;
  178. }
  179. ``
  180. In addition, for each version macro defined there is an
  181. `*_AVAILABLE` macro defined only when the particular aspect is
  182. detected. I.e. a definition equivalent to:
  183. ``
  184. #if BOOST_PREDEF_ABC
  185. #define BOOST_PREDEF_ABC_AVAILABLE
  186. #endif
  187. ``
  188. Also for each aspect there is a macro defined with a descriptive
  189. name of what the detection is.
  190. [heading The `*_EMULATED` macros]
  191. Predef definitions are guaranteed to be uniquely detected within one category.
  192. But there are contexts under which multiple underlying detections are possible.
  193. The well known example of this is detection of GCC and MSVC compilers which are
  194. commonly emulated by other compilers by defining the same base macros. To
  195. account for this detection headers are allowed to define `*_EMULATED` predefs
  196. when this situation is detected. The emulated predefs will be set to the
  197. version number of the detection instead of the regular predef macro for that
  198. 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`.
  199. [heading Using the `BOOST_VERSION_NUMBER` macro]
  200. All the predefs are defined to be a use of the `BOOST_VERSION_NUMBER` macro.
  201. The macro takes individual major, minor, and patch value expressions:
  202. ``
  203. #define BOOST_VERSION_NUMBER( major, minor, patch ) ...
  204. ``
  205. The arguments are:
  206. # Major version number, as a constant value expression in the range [0,99].
  207. # Minor version number, as a constant value expression in the range [0,99].
  208. # Patch-level version number, as a constant value expression in the
  209. range [0,99999].
  210. The ranges for each are "enforced" by the use of a modulo ("%"), i.e. truncation,
  211. as opposed to a clamp. And hence this means that the limits are enforced only
  212. enough to keep from having out-of-range problems. But not enough to prevent
  213. other kinds of problems. Like exceeding the range and getting false detections,
  214. or non-detections. It is up to the individual predefs to ensure correct
  215. usage beyond the range guarantee.
  216. The values for the arguments can be any preprocessor valid constant value expression.
  217. Only constant value arithmetic is used in the definition of the `BOOST_VERSION_NUMBER`
  218. macro and in any of the other predef macros. This means that any allowed base is
  219. possible, i.e. binary, octal, decimal, and hexadecimal. For example:
  220. ``
  221. #define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,0xA,015)
  222. ``
  223. Is equivalent to:
  224. ``
  225. #define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,10,13)
  226. ``
  227. [endsect]
  228. [section Adding new predefs]
  229. We know that a library like this one will be an eternal work-in-progress. And
  230. as such we expect, and look forward to, others contributing corrections and
  231. additions to the predefs. With that in mind we need to keep a consistent way
  232. of defining the new predefs. Hence all current, and future, predefs follow
  233. the same structure and requirements.
  234. [heading Requirements of the header]
  235. All predefs need to follow a set of requirements:
  236. * The headers must use the Boost Software License.
  237. * The predef must, by default, be defined as `BOOST_VERSION_NUMBER_NOT_AVAILABLE`.
  238. * The predef must be redefined to a non-zero value once detected.
  239. * The predef must, by default, be defined to `BOOST_VERSION_NUMBER_AVAILABLE`
  240. when the predef is detected.
  241. * If possible, the predef will be defined as the version number detected.
  242. * The predef must define `*_AVAILABLE` macros as needed.
  243. * The predef must define a symbolic constant string name macro.
  244. * The predef must declare itself, after being defined, for the testing
  245. system.
  246. * The predef must guarantee that it is the only one defined as detected
  247. per category.
  248. * But a predef can define `*_EMULATED` macros to indicate that it was
  249. previously detected by another header and is being "emulated" by the
  250. system. Note that the `*_AVAILABLE` macros must still be defined in this
  251. situation.
  252. And there are some extra guidelines that predef headers should follow:
  253. * The detection should avoid including extra headers that might otherwise
  254. not be included by default.
  255. * If the detection must include a header, prefer guarding it within the
  256. detection if possible.
  257. * If the detection must include headers unconditionally, and has a choice
  258. of headers to include, prefer the ones with the least impact. I.e.
  259. include the one with the minimal set of definitions and other
  260. dependencies.
  261. [heading Structure of the header]
  262. For general consistency it's suggested that new predef headers follow the
  263. structure below, as current predef headers do. First we have the copyright
  264. and license statement, followed by the include guard:
  265. ``
  266. /*
  267. Copyright Jane Doe YYYY
  268. Distributed under the Boost Software License, Version 1.0.
  269. (See accompanying file LICENSE_1_0.txt or copy at
  270. http://www.boost.org/LICENSE_1_0.txt)
  271. */
  272. #ifndef BOOST_PREDEF_category_tag_H
  273. #define BOOST_PREDEF_category_tag_H
  274. ``
  275. If the detection depends on the detection of another predef you should
  276. include those headers here.
  277. ``
  278. #include <boost/predef/CATEGORY_TAG/DEPENDENCY.h>
  279. ``
  280. Depending on how you are defining the predef you will at minimum have
  281. to include the `version_number.h` header. But you might also want to
  282. include the `make.h` header for the version number decomposing utility
  283. macros:
  284. ``
  285. #include <boost/predef/version_number.h>
  286. #include <boost/predef/make.h>
  287. ``
  288. The Predef library uses Quickbook for documentation and for the
  289. individual predefs to appear in the reference section we add in-code
  290. documentation followed by the zero-value default definition of the
  291. predef macro. We strongly recommend this particular placement of the
  292. documentation and default definition because some development
  293. environments automatically interpret this and provide in-line help
  294. for the macro. In particular this works for the popular Eclipse IDE:
  295. ``
  296. /*`
  297. [heading `BOOST_category_tag`]
  298. Documentation about what is detected.
  299. */
  300. #define BOOST_category_tag BOOST_VERSION_NUMBER_NOT_AVAILABLE
  301. ``
  302. Next is the detection and definition of the particular predef. The
  303. structure for this is to do a single overall check (`condition_a`) and
  304. place further version detection inside this. The first action inside
  305. the overall check is to "`#undef BOOST_category_tag`" which undefines
  306. the zero-value default. The rest is up to the you how to do the checks
  307. for defining the version. But at minimum it must
  308. "`#define BOOST_category_tag BOOST_VERSION_NUMBER_AVAILABLE`" as the fallback
  309. to minimally indicate that the predef was detected:
  310. ``
  311. #if (condition_a)
  312. # undef BOOST_category_tag
  313. # if (condition_b)
  314. # define BOOST_category_tag BOOST_VERSION_NUMBER(major,minor,patch)
  315. # else
  316. # define BOOST_category_tag BOOST_VERSION_NUMBER_AVAILABLE
  317. # endif
  318. #endif
  319. ``
  320. We also need to provide the `*_AVAILABLE` versions of the predef.
  321. ``
  322. #if BOOST_category_tag
  323. # define BOOST_category_tag_AVAILABLE
  324. #endif
  325. ``
  326. And for convenience we also want to provide a `*_NAME` macro:
  327. ``
  328. #define BOOST_category_tag_NAME "Name"
  329. ``
  330. The testing of the predef macros is automated to generate checks for all
  331. the defined predefs, whether detected or not. To do this we need to
  332. declare the predef to the test system. This declaration is empty for
  333. regular use. And during the test programs they expand out specially
  334. to create informational output:
  335. ``
  336. #include <boost/predef/detail/test.h>
  337. BOOST_PREDEF_DECLARE_TEST(BOOST_category_tag,BOOST_category_tag_NAME)
  338. ``
  339. And, of course, we last need to close out the include guard:
  340. ``
  341. #endif
  342. ``
  343. [heading Adding exclusive predefs]
  344. For headers of predefs that need to be mutually exclusive in the detection
  345. we need to add checks and definitions to detect when the predef is
  346. detected by multiple headers.
  347. Internally compiler, operating system, and platforms define
  348. `BOOST_PREDEF_DETAIL_COMP_DETECTED`, `BOOST_PREDEF_DEFAIL_OS_DETECTED`, and
  349. `BOOST_PREDEF_DETAIL_PLAT_DETECTED` respectively when the predef is first
  350. detected. This is used to guard against multiple definition of the detection
  351. in later included headers. In those cases the detection would instead be
  352. written as:
  353. ``
  354. #if !BOOST_PREDEF_DETAIL_category_DETECTED && (condition_a)
  355. # undef BOOST_category_tag
  356. # if (condition_b)
  357. # define BOOST_category_tag BOOST_VERSION_NUMBER(major,minor,patch)
  358. # else
  359. # define BOOST_category_tag BOOST_VERSION_NUMBER(0,0,1)
  360. # endif
  361. #endif
  362. ``
  363. And we also include a header that defines the `*_DETECTED` macro when we have
  364. the detection:
  365. ``
  366. #if BOOST_category_tag
  367. # define BOOST_category_tag_AVAILABLE
  368. # include <boost/predef/detail/CATEGORY_detected.h>
  369. #endif
  370. ``
  371. Everything else about the header is the same as the basic detection header.
  372. [heading Adding an exclusive but emulated predef]
  373. Because compilers are frequently emulated by other compilers we both want
  374. to have exclusive detection of the compiler and also provide information
  375. that we detected the emulation of the compiler. To accomplish this we define
  376. a local `*_DETECTION` macro for the compiler detection. And conditionally
  377. define either the base compiler predef `BOOST_COMP_compiler` or the alternate
  378. `BOOST_COMP_compiler_EMULATED` predef.
  379. The initial detection would look like:
  380. ``
  381. #if (condition_a)
  382. # if (condition_b)
  383. # define BOOST_COMP_tag_DETECTION BOOST_VERSION_NUMBER(major,minor,patch)
  384. # else
  385. # define BOOST_COMP_tag_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
  386. # endif
  387. #endif
  388. ``
  389. And then we can conditionally define the base or emulated predefs:
  390. ``
  391. #ifdef BOOST_COMP_tag_DETECTION
  392. # if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
  393. # define BOOST_COMP_tag_EMULATED BOOST_COMP_tag_DETECTION
  394. # else
  395. # undef BOOST_COMP_tag
  396. # define BOOST_COMP_tag BOOST_COMP_tag_DETECTION
  397. # endif
  398. # define BOOST_category_tag_AVAILABLE
  399. # include <boost/predef/detail/comp_detected.h>
  400. #endif
  401. ``
  402. [heading Using utility pattern macros]
  403. By including:
  404. ``
  405. #include <boost/predef/make.h>
  406. ``
  407. One will get a set of utility macros to decompose common version
  408. macros as defined by compilers. For example the EDG compiler
  409. uses a simple 3-digit version macro (M,N,P). It can be decomposed
  410. and defined as:
  411. ``
  412. #define BOOST_COMP_EDG BOOST_PREDEF_MAKE_N_N_N(__EDG_VERSION__)
  413. ``
  414. The decomposition macros are split into three types: decimal
  415. decomposition, hexadecimal decomposition, and date decomposition.
  416. They follow the format of using "N" for decimal, "F" for hexadecimal,
  417. and "Y", "M", "D" for dates.
  418. [endsect]
  419. [def __predef_symbol__ Symbol]
  420. [def __predef_version__ Version]
  421. [def __predef_detection__ *detection*]
  422. [section Reference]
  423. [section `BOOST_ARCH` architecture macros]
  424. [include ../include/boost/predef/architecture/*.h]
  425. [include ../include/boost/predef/architecture/x86/*.h]
  426. [endsect]
  427. [section `BOOST_COMP` compiler macros]
  428. [include ../include/boost/predef/compiler/*.h]
  429. [endsect]
  430. [section `BOOST_LANG` language standards macros]
  431. [include ../include/boost/predef/language/*.h]
  432. [endsect]
  433. [section `BOOST_LIB` library macros]
  434. [include ../include/boost/predef/library/c/*.h]
  435. [include ../include/boost/predef/library/std/*.h]
  436. [endsect]
  437. [section `BOOST_OS` operating system macros]
  438. [include ../include/boost/predef/os/*.h]
  439. [include ../include/boost/predef/os/bsd/*.h]
  440. [endsect]
  441. [section `BOOST_PLAT` platform macros]
  442. [include ../include/boost/predef/platform/*.h]
  443. [endsect]
  444. [section `BOOST_HW` hardware macros]
  445. [include ../include/boost/predef/hardware/*.h]
  446. [endsect]
  447. [section Other macros]
  448. [include ../include/boost/predef/other/*.h]
  449. [endsect]
  450. [section Version definition macros]
  451. [include ../include/boost/predef/version_number.h]
  452. [include ../include/boost/predef/make.h]
  453. [endsect]
  454. [endsect]
  455. [section Check Utilities]
  456. The `predef_check` utility provides a facility for building a
  457. program that will check a given set of expressions against
  458. the definitions it detected when it was built.
  459. [heading [^predef_check] programs]
  460. Even though there is only one `predef_check` program, there
  461. are variations for each of the languages that are detected
  462. by Predef to match the convention for sources files. For all
  463. of them one invokes with a list of expression arguments. The
  464. expressions are evaluated within the context of the particular
  465. [^predef_check] program and if they all are true zero (0) is returned.
  466. Otherwise the index of the first false expression is returned.
  467. The expression syntax is simple:
  468. [teletype]
  469. ``
  470. predef-definition [ relational-operator version-value ]
  471. ``
  472. [c++]
  473. [~predef-definition] can be any of the Predef definitions. For
  474. example `BOOST_COMP_GCC`.
  475. [~relational-operator] can be any of: [^>], [^<], [^>=], [^<=],
  476. [^==] and [^!=].
  477. [~version-number] can be a full or partial version triplet value.
  478. If it's a partial version triple it is completed with zeros. That
  479. is [^x.y] is equivalent to [^x.y.0] and [^x] is equivalent to
  480. [^x.0.0].
  481. The [~relations-operator] and [~version-number] can be ommited. In
  482. which case it is equivalent to:
  483. [teletype]
  484. ``
  485. predef-definition > 0.0.0
  486. ``
  487. [c++]
  488. [heading Using with Boost.Build]
  489. You can use the [^predef_check] programs directly from Boost Build
  490. to configure target requirements. This is useful for controlling
  491. what gets built as part of your project based on the detailed
  492. version information available in Predef. The basic use is simple:
  493. [teletype]
  494. ``
  495. import path-to-predef-src/tools/check/predef
  496. : check require
  497. : predef-check predef-require ;
  498. exe my_windows_program : windows_source.cpp
  499. : [ predef-require "BOOST_OS_WINDOWS" ] ;
  500. ``
  501. [c++]
  502. That simple use case will skip building the [^my_windows_program]
  503. unless one is building for Windows. Like the direct [^predef_check]
  504. you can pass mutiple expressions using relational comparisons.
  505. For example:
  506. [teletype]
  507. ``
  508. import path-to-predef-src/tools/check/predef
  509. : check require
  510. : predef-check predef-require ;
  511. lib my_special_lib : source.cpp
  512. : [ predef-require "BOOST_OS_WINDOWS != 0" "BOOST_OS_VMS != 0"] ;
  513. ``
  514. [c++]
  515. And in that case the [^my_special_lib] is built only when the OS is
  516. not Windows or VMS. The [^requires] rule is a special case of the
  517. [^check] rule. And is defined in terms of it:
  518. [teletype]
  519. ``
  520. rule require ( expressions + : language ? )
  521. {
  522. return [ check $(expressions) : $(language) : : <build>no ] ;
  523. }
  524. ``
  525. [c++]
  526. The expression can also use explicit "and", "or" logical operators
  527. to for more complex checks:
  528. [teletype]
  529. ``
  530. import path-to-predef-src/tools/check/predef
  531. : check require
  532. : predef-check predef-require ;
  533. lib my_special_lib : source.cpp
  534. : [ predef-require "BOOST_OS_WINDOWS" or "BOOST_OS_VMS"] ;
  535. ``
  536. [c++]
  537. You can use the [^check] rule for more control and to implement
  538. something other than control of what gets built. The definition
  539. for the [^check] rule is:
  540. [teletype]
  541. ``
  542. rule check ( expressions + : language ? : true-properties * : false-properties * )
  543. ``
  544. [c++]
  545. When invoked as a reuirement of a Boost Build target this rule
  546. will add the [^true-properties] to the target if all the [^expressions]
  547. evaluate to true. Otherwise the [^false-properties] get added as
  548. requirements. For example you could use it to enable or disable
  549. features in your programs:
  550. [teletype]
  551. ``
  552. import path-to-predef-src/tools/check/predef
  553. : check require
  554. : predef-check predef-require ;
  555. exe my_special_exe : source.cpp
  556. : [ predef-check "BOOST_OS_WINDOWS == 0"
  557. : : <define>ENABLE_WMF=0
  558. : <define>ENABLE_WMF=1 ] ;
  559. ``
  560. [c++]
  561. For both [^check] and [^require] the [^language] argument controls
  562. which variant of the [^predef_check] program is used to check the
  563. expressions. It defaults to "c++", but can be any of: "c", "cpp",
  564. "objc", and "objcpp".
  565. [endsect]
  566. [include history.qbk]
  567. [include todo.qbk]
  568. [section Acknoledgements]
  569. The comprehensiveness of this library would not be
  570. possible without the existence of the indispensable
  571. resource that is the
  572. [@http://sourceforge.net/p/predef/ Pre-defined C/C++ Compiler Macros]
  573. Project. It was, and continues to be, the primary source
  574. of the definitions that make up this library. Thanks
  575. to Bjorn Reese and all the volunteers that make that
  576. resource possible.
  577. This library would be an incoherent mess if it weren't for
  578. Boost community that provided invaluable feedback for the
  579. eight years that it took to polish into a useable form.
  580. In particular I would like to thank: Mathias Gaunard,
  581. Robert Stewart, Joël Lamotte, Lars Viklund, Nathan Ridge,
  582. Artyom Beilis, Joshua Boyce, Gottlob Frege, Thomas Heller,
  583. Edward Diener, Dave Abrahams, Iain Denniston, Dan Price,
  584. Ioannis Papadopoulos, and Robert Ramey. And thanks to
  585. Joel Falcou for managing the review of this library.
  586. [endsect]