Strategies for Integrating External CPP Libraries

It is common to have external C++ libraries that should be linked with the final C++ application. It may be convenient to integrate the building of such an external library into the overall build process. To do so you may use a TC which has the “Artifact type” set to “C++ External Library”. For such a TC the “Target Configuration” tab contains properties which are used so that the generated makefile can include a target for building the external library from its sources.

Generate make file for external CDT project allows the external library to be built from a CDT project. If this property is set the "Build folder" property should specify a target folder for a CDT project. When the TC is built a makefile will be generated from the CDT project and the "Build command" should specify how to run make on that makefile in order to build the external library.

Note that the word "external" in the name of this property just means "external to the project that contains the TC". The CDT project is typically located in the same workspace as your model project.

Build command specifies a command that builds the external library. For example it can be an invocation of make with a makefile for the library.

Build folder specifies the folder where to run the build command.

Clean command specifies a command that cleans the external library. For example it can be an invocation of make clean with a makefile for the library.

CDT configuration name is only applicable if the setting "Generate make file for external CDT project" is enabled. In that case it can be used for specifying the name of the CDT configuration to build. If the "Build folder" already specifies a target folder for the CDT project that has the same name as the configuration (which is typical), then you don't have to specify the name of the configuration here. It will be deduced from the "Build folder" setting instead.

Inclusion paths is a list of inclusion paths where the header files of the external library are located. These paths will be added to the include paths in the makefile that is generated for a TC which has the external library TC as a prerequisite.

Libraries is a list of libraries that will be added to the list of libraries in the makefile that is generated for a TC which has the external library TC as a prerequisite. Typically you would here enter the libraries that are produced by running the build command.

External library TCs also have another special property Include file name in its “Code Generation” tab. It specifies an include file to be included by code that uses the external library. At most one include file can be included for the library. If you need to include more than that you have to create a wrapper include file which includes all the required files. The include file for the external library will be included by the unit header (by default called UnitName.h) for each TC which has the external library TC as a prerequisite TC.

Note that an external C++ library TC does not specify a target project.

The picture below shows an example of a C++ External Library TC which is configured to build the library from a CDT project.

When this TC is built a makefile is first generated for the CDT project Pi_libraryFunc which should be available in the workspace. The CDT configuration "Debug" will be used, since that target folder is specified in the "Build folder" property. The makefile is processed using the build command "$(MAKE) all" which will build the library "libPi_libraryFunc.a".

Precompiled Libraries

Some external libraries are rarely modified. You may want to avoid to rebuild such libraries each time you build your model, and instead link directly with a precompiled library. The precompiled library is stored in a location that is available to everyone who has to build the model. To achieve this you may leave the "Build command" and the "Build folder" properties empty in the "C++ External Library" TC. For example:

When you build an executable TC that has this TC as a prerequisite no actions will be performed to build the precompiled library. Instead the library specified in "Libraries" will be directly used when linking the executable. This makes the build of the executable TC faster, since the library does not have to be built.

If the precompiled library is built from a UML model you may specify model elements in its "Sources" property. The code generator will automatically generate #includes for all classes mentioned there, if the property Generate class inclusions is enabled. The #includes are generated in C++ implementation files that are generated from TCs that have the external library TC as a prerequisite, and that contain model elements which use the source classes.

You also need another TC (a "C++ Library" TC) which can be used to build the precompiled library, in case the model has been changed. A typical workflow is that one person changes the model for the precompiled library and then builds it using the "C++ Library" TC. Then he takes the resulting library file ("library.a" in the above example) and puts it in the location which is specified in the "Libraries" setting of the precompiled library TC. This location is typically a shared network folder, or a location in the CM system. Thereby the precompiled library becomes available for other users who need to build a model that uses it.

External Constants

By using different ”C++ External Library” TCs in different builds it is possible to build multiple variations of an application. The interface of the external library remains the same, but its implementation can vary between different builds, for example depending on target platform or build configuration (debug / release etc).

Sometimes it's not enough to only let the implementation of a library differ. The different variations of an application may also need to be built using different values for certain constants that are used in the model. For example, the multiplicity of a replicated port may be specified by means of a constant that should have different values in different variations of the application. For this usecase external constants can be used.

An external constant is a constant that is used in the model, but its value is not defined in the model. Instead, the value is defined using a ”C++ External Library” TC (and can therefore be different for different builds of the application).

The “Target Configuration” tab contains properties that can be used for defining the values of external constants that are used in the model. The easiest way to define the values is to write them in the Constants field using a simple “NAME = VALUE” syntax. The VALUE can be any constant expression, and it will be evaluated by the model compiler when building the model. The expression may contain references to user-defined variables (see User-defined Variables ), and you may use C++ style comments (// …) as necessary. For example:

POOL_SIZE = 100
// MYSIZE is a user-defined variable
PORT_BUF = $(MYSIZE) * 2

It's also possible to provide values for the external constants in a file. The file can either be a C/C++ header file (with the file extension .h) or it can be a plain text file (with any other file extension). In the latter case the text file should use the same syntax as is used in the Constants field in the TC. For a C/C++ header file regular C/C++ syntax should be used, and constants can then be defined either as macros or const definitions. For example:

// Constants defined in a C/C++ header file
#define POOL_SIZE 200
const int FILE_CONST = 13;

A file that defines external constants is referenced from the Constants field in the “C++ External Library” TC. You may either use an absolute or a workspace relative path. In the latter case the path should be preceded by the character '@'. For example:

// Workspace relative path
@/SomeCppProject/const.h
// Absolute path
C:\temp\constants.txt

If the same constant is defined multiple times, then the last definition will be used to obtain its value.

A “C++ External Library” TC can bring in values for external constants that are defined in another “C++ External Library” TC by adding that TC as a prerequisite. If necessary it can override the values for some of those external constants by providing different values for them.

Defining External Constants Programmatically

A “C++ External Library” TC has a setting Constant provider which can refer to a plugin in order to provide values for external constants programmatically. The plugin should have a class with a static method that will be called to obtain the values for the external constants. The method should have the following signature:

public static Map<String, String> void NAME(
    ITransformContext context, // current transformation context
    String transformURI,     // URI of TC
    IProgressMonitor monitor)  // current progress monitor

The implementation of this method should return a map which provides the names of the external constants and their corresponding values.

You should refer to this method from the “Constant provider” field using the syntax

<qualified plugin name>/<qualified class name>/<method name>

For example:

cpp com.acme.extConstantPlugin/com.acme.ExtConstantClass/getExternalConstants

Note that constant values provided by a constant provider plugin override values provided by the Constants property.