| |
| [section:build_config Build Time Configuration] |
| |
| There are times when you want to control whether a build target gets built or not, based |
| on what features the compiler supports. For example, suppose you have a test file |
| "test_constexpr_128.cpp" which requires three key features in order to build: |
| |
| * The `constexpr` keyword as detected by BOOST_NO_CXX11_CONSTEXPR. |
| * User defined literals, as detected by BOOST_NO_CXX11_USER_DEFINED_LITERALS. |
| * The `__int128` data type, as detected by BOOST_HAS_INT128. |
| |
| Clearly we know that if these features are not supported by the compiler, then |
| there's simply no point in even trying to build the test program. The main advantages being: |
| |
| * Faster compile times - build configuration uses lightweight tests the results of which are also cached. |
| * Less noise in build output - there's no reason to be faced with pages of template |
| instantiation backtrace if we know the file can never compile anyway. |
| * Less noise in the online test results - the test will show up as blank, rather than as a fail |
| in the online test matrix. |
| * A better experience for end users building all of Boost, if those libraries which can not be built |
| for the current target compiler are simply skipped, rather than generating pages of error output. |
| |
| Returning to our example, the test case is probably executed in it's Jamfile via the "run" rule: |
| |
| run test_constexpr_128.cpp ; |
| |
| We now need to make this target conditional on the necessary features. |
| We can do that by first importing the necessary rule at the start of the Jamfile: |
| |
| import path-to-config-lib/checks/config : requires ; |
| |
| Assuming that the test case is in the usual directory: |
| |
| libs/yourlib/test |
| |
| then the import rule will actually be: |
| |
| import ../../config/checks/config : requires ; |
| |
| Then add a "requires" rule invocation to the requirements section of the target: |
| |
| run test_constexpr_128.cpp |
| : : : #requirements: |
| [ requires cxx11_constexpr cxx11_user_defined_literals int128 ] ; |
| |
| Notice that multiple arguments can be added to the requires rule, and that these are |
| always the same as the Boost.Config macro name, but in lower case and with the ['boost_no_] |
| or ['boost_has_] prefix removed. |
| |
| When building the above example, you will see at the start of the build process the results |
| of the configuration, for example GCC in C++11 mode gives: |
| |
| - Boost.Config Feature Check: int128 : yes |
| - Boost.Config Feature Check: cxx11_constexpr : yes |
| - Boost.Config Feature Check: cxx11_user_defined_literals : yes |
| |
| That's all there is to this handy feature, should at any time you be unsure of the feature-test |
| names you can pass to the "requires" rule, then search for the Boost.Config macro of interest in |
| libs/config/checks/Jamfiles.v2, and the name of the feature check will follow it. |
| |
| And finally, this feature is built around the Boost.Build built in rule ['check-target-builds] |
| which can be used to perform more generalized build-time feature testing. The checks in this |
| library are provided as a convenient shorthand without the need for you to write the test cases yourself. |
| |
| [endsect] |