Since its V4 release, PID provides a way to specify requirements on the host configuration directly in packages. This is usefull to:
- check that a language is available and check its specific features.
- use specific compiler toolchains.
- explicitly require the use of third party tools.
Step 1: Management of languages used in packages
1.1: Changing toolchains
To understand how to specifcy constraints on build system, let’s start with a simple example. We suppose we have a package, called
Now we simply want to enforce the use of a specific compiler, for instance
clang with a minimal version, let’s say 3.8. Its CMake description looks like:
All requirements on host configuartion are performed using the
check_PID_Environment function. The
LANGUAGE keyword specifcies which language we want to configure, here
c++ denoted by its CMake language identifier
CXX. To target a language you must use a CMake standard language identifiers
TOOLSET keyword is then used to specifcy which toolchain you want to use. In this example we use the
clang_toolchain. This name must match an existing environment that defines a toolchain for the target language. Furthermore you can use constraints expressions (like for target platform checks) to specifcy more constraints on the environment. Here we say that we want the minimum version 3.8 to be used. This is possible since the
clang_toolchain environment defines such constraint.
When tha package is configured, the PID system will look into current profile if this environment, with matching constraints, is defined. If not, then it will:
- try to deploy the
clang_toolchainin workspace if not already available.
- then evaluate it to generate a configuration that matches the requirements (i.e.g a
clangcompiler toolchain with version 3.8 or more).
If everything works well, the package will be configured to use the
clang compiler anytime the package needs to build
c++ code, instead of default compiler toolchain defined in current profile.
- The current profile will not be modified by this actions, so if it does not define alternative toolchains that match the constraints, the package will need to reevaluate the
clang_toolchainany time the package is configured. So in the end it is a good approach to add
clang_toolchain[version=3.8]to current profile “by hand” so that it will be evaluated once and for all. The package will then simply reuse this compatible host configuration without reevaluating the environment. Have a look at the tutorial on profiles management to understand how to do that.
- As far as possible, you should avoid forcing the use of a specific toolchain. It should be reserved to the casse when you use specific compiler features that are provided only by the given toolchain.
1.2: Specifying constraints on languages
Another way to configure language is to define constraints directly on languages, using constraint expressions.
For instance, let’s suppose you wrote
c++17 code inside the
test-host package, so you defined components that explicitly use the C++ 17 standard (using
CXX_STANDARD argument of
PID_Component). But nothing ensure that the default compiler is trully capable of building c++17 code ! One way to ensure that is to enforce a constraint on host configuration:
LANGUAGE keyword is used to tell that we want to check the configruation of a specific language, here
c++. But now we use a constraint expression,
[std=17], to specificy that the package needs a compiler with full support to c++17 standard.
We could also want to use available processor optimizations when building c++ code, so we can write:
The use of
native value for
optimization simply tells the system to use every possible optimization, so it is not a hard constraint. But if the code requires a specific optimization, which obviously is a very rare situation, we could have written:
The package now explicitly requires optimizations
AVX512_SKX. This could be the case for instance if the code is written for a specific family of processors. Possible values of the
optimization constraints are given anytime the workspace is configured:
Have a look at the line processor family:
- At the time this documentation is written,
stdsupports different set of values for
CXX(depending on the available standards for the two languages) while
optimizationsupport same set of values for both.
- To know possible constraints implemented for each language use the
Output looks like:
Step 2: Management of specific tools
Now let’s reuse the description of the
eigen-qp package. You can deploy this package this way:
CMakeLists.txt looks like:
The important part here is the use of the
We first specify that the package uses the
Fortran language by default:
We need to use such expression simply because the
eigen-qp package contains
Fortran source code.
The call is straightforward: the
LANGUAGE keyword is used to tell that we want to check a language and
OPTIONAL is used to avoid to generate an error if
Fortran is not available for target platform. The call generates the variable
Fortran_ENVIRONMENT that is TRUE if
Fortran language has been found and FALSE otherwise.
In case it is not available, we want to use an alternative: generate
C code using the
f2c tool and then compile it. We so need to check that the extra too
f2c is available:
Here we use the
TOOL keyword to specify that we want to use a tool (a code generator) that is not natively supported by CMake.
OPTIONAL is not used so if
f2c is not usable on host platform then an error is generated and the package configuration stops. This is normal since we have no other alternative.
Everything in this situation is automatic: either the
Fortran compiler is directly used to generate binaries or
C code and then this code is compiled to generate binaries. In the end, the description of components does not change whatever the compilation process is, for instance:
As you can see there is no specific CMake code to deal with the two alternatives. This is mainly due to the fact that the
f2c plugin behavior, when used, automatically adds a dependency to the
f2c library. To understand how these plugin behavior can be written you can refer to this tutorial.