Use interfaces from an imported Sen-based project¶
This guide will focus on how to set up your project to consume interfaces from external packages. For this guide to be accurate, the package you consume should have followed the instructions described on the how to export interfaces in Sen-based projects guide.
How to consume Sen-based projects as CMake packages¶
To use an external project's interfaces you first need the project itself, and you consume it
through CMake. Every Sen-based project is exported as a CMake package, and you can get that package
in several ways: the Conan package manager, ZIP files, CMake installations, and so on. It does not
matter which one you use. Every project ships a -config.cmake file, and the only requirement is
that the directory containing it is on the CMAKE_PREFIX_PATH.
Setting the CMAKE_PREFIX_PATH depends on the method you choose to consume the package:
- If you consume a Sen-based package via Conan, the
CMAKE_PREFIX_PATHwill be set automatically. - If you use ZIP files or CMake installations, you will need to provide the correct path to the
directory before calling CMake's
find package.
After ensuring that the project's CMake directory is added to the CMAKE_PREFIX_PATH variable, we
can now call
to add the consumed project to yours. Sen uses an independent CMake file for each dependency, so the
recommendation is to follow the same architecture. You can check Sen's dependencies located in
cmake/tps or the dependencies of any Sen-based project (e.g. a Sen-based gateway project) under
cmake/deps for further detail.
Use external interfaces inside your project¶
After importing the external project into yours, you can use Sen's CMake tools to use the interfaces of an externally included project.
get_external_interfaces function¶
Sen's CMake utils implement the get_external_interfaces() function. This function receives the
name of any Sen-based CMake target with an STL interface, and an installation dir, which should
point to the directory where Sen is installed and being consumed externally:
- The
TARGETargument will be the name of the desired CMake target who you want to obtain the interfaces from. The target name will stay the same as it is on the original project, preceded by its namespace. For example, if I want to obtain Sen's recorder component interfaces, I would callget_external_interfaces(TARGET sen::recorder ...). - The
INSTALLATION_DIRargument is a variable that points to the actual directory where the imported package is located at compile time. If the CMake package of the consumed project was generated using the how to export interfaces in Sen-based projects guide, this variable should be set to*project_name*_INSTALL_DIR. If the variable is not set the function call will fail, showing possible solutions of the problem, ultimately leading to contact the maintainer of the consumed project.
Calling the get_external_interfaces function will add new CMake properties to the target that can
later be used to generate code making use of Sen's CMake generation functions (sen_generate_cpp,
sen_generate_package, add_sen_package, etc.).
Generating code using external interfaces¶
After calling get_external_interfaces, CMake will add additional properties to the given TARGET
that were not present at the time of building. These two are always set:
INSTALL_BASE_PATH: Set BASE_PATH when generating the packages originally but adapted to point at the installation dir.INSTALL_SEN_IMPORT_DIRS: The-iimport search path the generator resolvesstlimports through, pointing at the installation dir rather than the tree that built the package.
The rest are set only when the consumed component has files of that kind:
INSTALL_STL_FILES: List of paths to each of the component's STL files in the installation dir.INSTALL_HLA_FOM_DIRS: List of paths to each of the component's defined HLA_FOM_DIRS in the installation dir.INSTALL_HLA_MAPPINGS: List of paths to the component's HLA mapping files in the installation dir.INSTALL_HLA_EXTENSIONS: List of paths to the component's HLA extension files in the installation dir.
You can use CMake's get_target_property function to fetch the value of these properties into local
variables. With these variables filled, you will be able to call Sen's code generation functions
with the files used to generate code on the original target. This allows replicating the generated
code of the original package, but allowing it to be imported into your project, added as a
dependency of your Sen Packages, etc.
Importing generated code¶
If the consumed project followed the
how to export interfaces in Sen-based projects guide, you will be able
to import the stl files in exactly the same way as they are imported in the original project.
This applies to stl inclusions (import "stl/sen/components/recorder/recorder.stl"), CPP
(#include "stl/sen/components/recorder/recorder.stl.h") or any language supported by Sen.
Note that you are not only limited to STL interfaces as HLA FOM files can also be exported in the same way.
Usage example¶
In this use case example, I have a component called Town. The town component resides in my
project, but it wants to use the interfaces of the already created school component, present on
the Sen project. The steps to follow would be:
1. Import Sen's CMake package by consuming it via Conan (or any other method to obtain packages)
and call find_package accordingly.
2. In your project's CMake files, call the get_external_interfaces function with the adequate
arguments:
3. Obtain both the stl files list and the BASE_PATH with get_target_property calls,
storing them in local CMake variables:
get_target_property(school_base_path sen::school INSTALL_BASE_PATH)
get_target_property(school_stl_files sen::school INSTALL_STL_FILES)
4. Use the locally filled variables to generate the cpp code of the school interfaces:
sen_generate_cpp(TARGET sen_school_interfaces
BASE_PATH ${school_base_path}
STL_FILES ${school_stl_files})
NOTE: if the interfaces you are using depend on any other interfaces (e.g., Sen recorder interface
depends on sen::db library interfaces), you need to generate them with a Sen code generation
function that allows adding dependencies with the DEPS argument. These two functions are
add_sen_component and add_sen_package.
5. After generating the code of the interfaces, you can use the obtained target
sen_school_interfaces inside your Sen packages:
add_sen_package(TARGET town
SOURCES ${town_sources}
BASE_PATH ${town_source_dir}
STL_FILES ${town_source_dir}/stl/sen/components/town/town.stl
DEPS sen_school_interfaces)
With the interfaces as a dependency, you will be able to import their STL files in any file of your Sen package.
- In STL files:
// town.stl file
import "stl/school/student.stl"
package town;
// What the schools we oversee last reported.
sequence<school.StudentStatus> StatusList;
class EducationCouncil
{
var neededTaxIncome : f32;
var reportedStatuses : StatusList [confirmed];
}
Note what crosses the boundary here: school.StudentStatus is a value type, and value types are
what properties can hold. A class such as school.Student cannot be a property type. To work with
another package's objects you discover them at run time and hold them through the generated
interface, as below.
- In CPP files: