Discussion about PidPath objects
The rpath
library provides a PidPath object that is used to describe and manage path to runtime resources in the context of a PID workspace. We can distinguish 3 main types of pid path:
absolute path
They have the classical form /home/user/dir/file
.
Their use is really not recommanded.
static relative path
They are expressed as classical relative path in unix filesystem : dir/file
. They are static because they must have been declared as dependent resources at build time using for instance:
- Declare a direct runtime dependency to a file or folder:
- Declare a runtime dependency to an application:
or directly within component declaration:
- Declare a runtime dependency to a module library:
or directly within component declaration:
dynamic relative path
They are unknown at build time so the dependency is not explicit until runtime. This way it is possible for a component to retrive a resource from arguments passed by to the program or from configuration files. They have a specific syntax decomposed in the following sequence of items:
-
a target package description with format
<package name,version constraint>
. Thepackage name
is a simple string naming the target package andversion constraint
specifies the search constraint. If the constraint is not respected (no version of the package was found wit hmatching requirements) then it throws an exception. Version constraints can specify:- an exact version, for example
<pid-rpath, 1.7.0>
searches for the exact version1.7.0
of packagepid-rpath
. - a minimal version, for example
<pid-rpath, +1.7.0>
searches for the maximum version that is greater or equal than1.7.0
. - a maximal version, for example
<pid-rpath, -1.7.0>
searches for the maximal version that is less or equal than1.7.0
. - an interval of versions, for example
<pid-rpath, 0.5.4~1.7.2>
searches for the maximal version that is the interval - any version, for example
<pid-rpath, any>
searches for the maximal version available.
- an exact version, for example
Please refer to the API doc of PidPath
class to learn possible constraints.
- a relative path expressed as classical relative path in unix filesystem :
dir/file
. This path is so made relative to the target package.
Specific modifiers
Whatever the type of path, PidPath also provides modifiers to be used at beginning of the expression:
- the write modifier
+
specifies that the target resource does not have to exist (i.e. it will be written by the program). - the module modifier
@
is used to specifiy a runtime component that is a module library (a dynamically loadable shared object). - the executable modifier
#
is used to specify a runtime component that is an application (an executable program).
All three modifiers are mutually exclusive. So anytime you define a runtime path to a runtime component (module or executable) this later must exist.
Using modifiers @
and #
requires:
- to define no path but to give only their name (as declared in the
CMakeLists.txt
file of the package that contains them). - to define the package they belong to (even if it is the same package as the one containing the source file) using a header like for a dynamic path.
So a static runtime path to a module looks like : @<package>component
, while a dynamic runtime path looks like @<package,constraint>component
. Same logic for executables.
The basics of static relative runtime resources
Any time you declare a static relative runtime resource for a given component (cf. previous section ), then:
-
All these runtime resources can be accessed by the component at runtime using static relative path. Futhermore the component will export all these resources so components that use it will be able to access these resources in turn.
-
if you use this resource in the code of the component (typically you will use path or file names), then you have to:
1) declare the component dependent from rpathlib:
or directly define it in component declaration using short signature.
2) include the rpathlib include in your source code:
3) use the pid-rpath API to manage all these path. It simply consists in using the dedicated “all-in-one” macro that does the whole job of finding for you:
- if you DO NOT use this resource in the code of the component (you use path or filename nowhere in its code), then you have nothing to do. This later case is simply used to allow components to export some resources even if they do not directly use them.
Remark: Using static relative runtime resource is far safer than with dynamic alternative as you know that these resources exist by construction (i.e. at build time) and will so be usable at runtime with adequate package version. Using dynamic relative path should be used only when it is not possible to know which runtime resources are required at build time (for instance when using a plugin based mechanism to dynamically load module libraries at runtime).
Exceptions
Be aware that PID_PATH
may throw exceptions if the target files or folders do not exist in the file system. All exception thrown are of type std::logic_error
, simply catch them as usual if you want to keep the program running.
Nevertheless, when you use static relative path like PID_PATH("a/path")
there should not be any exception in your program as all target resources should have been referenced before either directly (using RUNTIME_RESOURCES
in PID_Component
) or undirectly (recursively, by dependencies of the component). So these runtime resources are known at build time (nevertheless their content or even their existence in filesystem is unknown until execution) and so an exception should not be allowed in a debugged program…
Discussion about executable
Any time an executable that directly or undirectly (via libraries) uses runtime resources it should always begin like:
The PID_EXE
command initialize the system to let it know how to find relative runtime resources. Without this you will face exceptions. Its use can be omitted for most recent UNIX platforms.
Discussion about modules
Any time you want to use module library (in a plug-in based approach) you should always use the PID_MODULE
macro:
- when module is loaded use
PID_MODULE(true,"path/to/the/module")
. This must be done before any call to this module API (for instance just after adlopen
or equivalent call). - when module is unloaded use
PID_MODULE(false,"path/to/the/module")
. This must be done just after all call to the module API have been performed (for instance just after adlclose
or equivalent call).
As module are most of time used to dynamically add new functionnalities to an executable, they are unknown at executable build time. So static runtime resources they use are unknown in the executable context. The call to PID_MODULE
configures the executable so that it will also look into modules context to solve static relative runtime resources.