This part provides a detailed description on the usage of PID methodology’s core concepts and tools used to deal with
When developing a PID wrapper one needs to handle information such as:
- meta-information : who is involved in its development ? what is its general purpose ? where to find this package on the network ? what is the license of the code ? etc.
- build-related information : what are the components provided by the wrapper and how to compile/link them from source code ? How components are tested ? what is the version of the package ? what are its functional dependencies ?
The whole package development is organized and described with CMake, and the
CMakeLists.txt files used contain the whole meta-information and build-related information used by the wrapper. Each package contains several
CMakeLists.txt files that are generally used to define components :
- the root
CMakeLists.txtfile is used to define meta-information and dependencies of the wrapper.
CMakeLists.txtfiles contained in each version subfolder of the
srcfolder defines the components available for each version of the external package that is known into PID. They also reference a cmake deploy script that will be used to download, build and install the given version of the external project.
In the context of PID, components are software artefacts generated and installed by a package or a wrapper. Each component may require other components from another external package and so may explicitly define dependencies between wrappers. The primary role of PID is to manage these dependencies.
The wrapper general description takes place in the root
CMakeLists.txt. This file contains the description of meta-information of the wrapper.
Let’s suppose we define a wrapper for
yaml-cpp, its root
CMakeLists.txt could look like:
Exactly as in any CMake project, the CMake project is defined with the
PROJECTkeyword. The CMake project’s name must be the same as the name of the git repository and must be the same as the project root folder name. The previous lines must be let unchanged (initialization of the PID specific cmake API).
Then comes the
declare_PID_Wrapper) macro, which is mandatory. This macro defines general meta-information on the wrapper, and should not change a lot during wrapper life cycle:
- the main author (
AUTHORkeyword) and its institution (
INSTITUTIONoptional keyword), as well as his/her email (
YEARfield helps defining the wrapper’s life cycle range.
LICENSEfield is used to specify the license that applies to the wrapper code. This license must be defined in the workspace in the form of a license file.
ADDRESSfield is used to specify the address of the official GIT repository of the wrapper.
PUBLIC_ADDRESSfield is used to specify the public address of the same official GIT repository of the wrapper, public meaning that the clone can be done without any identification.
DESCRIPTIONfield must be filled with a short description of the wrapper usage/utility.
- the main author (
Then the user fill meta-information about original external project by using
PID_Original_Project(or equivalent long signature
AUTHORSkeyword help defining who are the authors of the original project, in order to clearly identify them.
LICENSESkeywork is used to list licenses applying to the original project code.
URLkeyword document where to find online documentation about original project.
Managed versions description
Then you have to create version subfolders in the
src folder of the wrapper. Each of these folders contains the the deployment procedure of the external project and the description of the content resulting from its build process. The whole version is described in a
CMakeLists.txt that looks like this:
PID_Wrapper_Version(equivalent signature is
add_PID_Wrapper_Known_Version) is used to declare the new version (using
VERSIONkeyword) and general information about it:
VERSIONmust be the same as the name of the containing folder.
DEPLOYis mandatory used to define the path to the cmake script file that implements the deploy procedure. The path is relative to the current version folder.
SONAMEmay be used to define which version number is used in SONAME of shared objects generated by the external project.
- Then platform configurations constraints are defined using
declare_PID_Wrapper_Platform_Configuration), exactly the same way as for native packages.
- Then dependencies to other external packages wrappers are defined using
declare_PID_Wrapper_External_Dependency), the same way as for native packages.
- Then components generated by the external project are described using
COMPONENTkeyword defines the PID name of the component
INCLUDESkeyword lists the include folders (if any) containing public headers of the component.
STATIC_LINKSlist the binaries and linker options of a library. Many binaries can be listed. All path used are either absolute (starting with a /) or relative to the external package version install folder.
- dependencies for these components are defined with
EXPORTkeywords. In this example
boost-headerscomponent provided by the
boostwrapper as well as libraries provided by the
Then you need at least to define a deployment script, as explained in
PID_Wrapper_Version. These deployment script are really scpecific to the considered external project being wrapped in PID. Here is an example of such a script for
yaml-cpp wrapper version 0.5.1:
The build process consists in first downloading and extracting the archive containing source files (using
install_External_Project function). Then since
boost we need to get the information where to find boost in local workspace using function
get_External_Dependencies_Info. Path to
boost root folder and include dirs are put into CMake variable that we need to pass to the
yaml-cpp project build process to compile it with adequate build options.
yaml-cpp is configured and build using
build_CMake_External_Project function. There are different function for the different build system already managed into PID. We do this two times: one time for building the static library and another one for shared library. One nice thing is taht we can pass CMake variables definitions (using
DEFINITIONS), for instance to configure the
Boost_INCLUDE_DIR folder variable of the original
yaml-cpp CMake project.
For other external package wrapper one needs to follow at best the same procedure.
Wrapper build process control
PID wrappers provide a set of cache variables that are used to control their build process. The configuration of these CMake cache variables is basically made using
ccmake .. command in the
build directory of the wrapper or by using other Cmake configuration GUI. Contrarily to native packages, wrapper do not provide default options, but they can define user specific options using dedicated API in the root
The wrapper defines an option called
BUILD_WITH_CUDA_SUPPORT that is a boolean that default to off.
This user option can be consulted in deploy script of versions in order to control the build process, this way:
Understanding the result
From the complete build/install process an “installed version” of the wrapper is generated and put into the adequate folder of the workspace. The install process is managed by PID system so developer should not worry about how it takes place.
The figure provides an example of the workspace’s
install folder containing yaml-cpp installed external packages wrappers for version 0.5.1 for a given platform (
x86_64_linux_stdc++11). There can be many versions of the same wrapper installed in the workspace for the same platform.
Each binary package version folder content is specific to the external project, but there is always a cmake use file (a file generated and used by PID to get information about the installed wrapper) is the
Generally speaking users should never change the content of any of those folders “by hand”, otherwise it could cause troubles.