]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | [section:build_config Build Time Configuration] | |
3 | ||
4 | There are times when you want to control whether a build target gets built or not, based | |
5 | on what features the compiler supports. For example, suppose you have a test file | |
6 | "test_constexpr_128.cpp" which requires three key features in order to build: | |
7 | ||
8 | * The `constexpr` keyword as detected by BOOST_NO_CXX11_CONSTEXPR. | |
9 | * User defined literals, as detected by BOOST_NO_CXX11_USER_DEFINED_LITERALS. | |
10 | * The `__int128` data type, as detected by BOOST_HAS_INT128. | |
11 | ||
12 | Clearly we know that if these features are not supported by the compiler, then | |
13 | there's simply no point in even trying to build the test program. The main advantages being: | |
14 | ||
15 | * Faster compile times - build configuration uses lightweight tests the results of which are also cached. | |
16 | * Less noise in build output - there's no reason to be faced with pages of template | |
17 | instantiation backtrace if we know the file can never compile anyway. | |
18 | * Less noise in the online test results - the test will show up as blank, rather than as a fail | |
19 | in the online test matrix. | |
20 | * A better experience for end users building all of Boost, if those libraries which can not be built | |
21 | for the current target compiler are simply skipped, rather than generating pages of error output. | |
22 | ||
23 | Returning to our example, the test case is probably executed in it's Jamfile via the "run" rule: | |
24 | ||
25 | run test_constexpr_128.cpp ; | |
26 | ||
27 | We now need to make this target conditional on the necessary features. | |
28 | We can do that by first importing the necessary rule at the start of the Jamfile: | |
29 | ||
30 | import path-to-config-lib/checks/config : requires ; | |
31 | ||
32 | Assuming that the test case is in the usual directory: | |
33 | ||
34 | libs/yourlib/test | |
35 | ||
36 | then the import rule will actually be: | |
37 | ||
38 | import ../../config/checks/config : requires ; | |
39 | ||
40 | Then add a "requires" rule invocation to the requirements section of the target: | |
41 | ||
42 | run test_constexpr_128.cpp | |
43 | : : : #requirements: | |
44 | [ requires cxx11_constexpr cxx11_user_defined_literals int128 ] ; | |
45 | ||
46 | Notice that multiple arguments can be added to the requires rule, and that these are | |
47 | always the same as the Boost.Config macro name, but in lower case and with the ['boost_no_] | |
48 | or ['boost_has_] prefix removed. | |
49 | ||
50 | When building the above example, you will see at the start of the build process the results | |
51 | of the configuration, for example GCC in C++11 mode gives: | |
52 | ||
53 | - Boost.Config Feature Check: int128 : yes | |
54 | - Boost.Config Feature Check: cxx11_constexpr : yes | |
55 | - Boost.Config Feature Check: cxx11_user_defined_literals : yes | |
56 | ||
57 | That's all there is to this handy feature, should at any time you be unsure of the feature-test | |
58 | names you can pass to the "requires" rule, then search for the Boost.Config macro of interest in | |
59 | libs/config/checks/Jamfiles.v2, and the name of the feature check will follow it. | |
60 | ||
61 | And finally, this feature is built around the Boost.Build built in rule ['check-target-builds] | |
62 | which can be used to perform more generalized build-time feature testing. The checks in this | |
63 | library are provided as a convenient shorthand without the need for you to write the test cases yourself. | |
64 | ||
65 | [endsect] |