Understanding TC Source Management

It is important to set-up the source elements of a TC properly. Ideally you want to transform only those elements that are really necessary to have in the C++ executable or library that results from building the TC. If you transform too many model elements the build will be slower since unnecessary C++ files have to be generated and compiled. Also, the produced binary files may become bigger than necessary. If all elements contained in a package should be part of the executable or library, you can specify that package as the only source element of a TC. This is convenient since you then don't have to update the Sources list each time new elements are added to the package. However, there is of course also the risk that you, at some point, add some model elements to the package that only are needed at model-level, and not in the C++ application. And this results in a longer than necessary build time, and possibly also a binary that is bigger than necessary.

Model RealTime has three features that can help you optimize the build to avoid building unnecessary source elements: Organize Sources, Detect Source Dependencies Automatically and Context Sensitive Library Builds. All these features work by analyzing references in the model to find out what elements that need to be included in the build.

Organize Sources

The TC editor provides a dialog that can assist you to set-up the Sources list in the optimal way. Open this dialog by pressing the \"Organize Sources\" button:

Before you can press this button you need to have specified the top capsule (for an executable TC) or at least one source element (for a library TC). The Organize Sources feature will use these elements as the starting point when analyzing references in the model to find out what elements that need to be built.

Here is an example of what the Organize Sources dialog may look like:

The upper table lists elements which you are suggested to add as sourceelements. For each element you can see the reference that is the reason for why that element needs to be a source element of the TC. If all elements in a package are needed source elements, then the package itself will be suggested to be added instead (to keep the Sources list short).

The lower table lists elements which are currently listed as source elements, but don't need to be so, because they are not referenced by other source elements or the top capsule. Here you may also find a package in case not all of its contents need to be transformed by the TC. Then the needed elements of the package are candidates to be added, and the package itself can be removed from the Sources list.

Note that Organize Sources only provides suggestions for how to update the Sources list to make it optimal. Use the checkboxes of each element to decide if you want to follow that suggestion or not. Then press the Finish button to update the Sources list.

It's important to be aware that all suggestions made by OrganizeSources are made by analyzing references in the model. References in C++ files will not be included in the analysis. Also, for a library it is possible (and even common) that you want to incl ude more elements than what is used by the library itself. Hence, it's important to carefullyreview all suggestions made by Organize Sources before updating the Sources list accordingly.

Sometimes an element that is referenced should still not be a source element of the TC because it\'s already the source element of a prerequisite TC in another project. To avoid building such an element twice you can use the checkbox \"Show only elements from current project\". Then referenced elements located in other projects will be filtered from the table, so you can avoid to add them. It can also help to use the checkbox \"Show fully qualified names\" to see where the elements are located.

If you use Organize Sources as your way of keeping the Sources element optimal, remember to invoke it at regular intervals. As you change your model, the Sources list may need to be updated again to remain optimal.

Detect Source Dependencies Automatically

If the preference RealTime Development -- Build/Transformations -- C++ -- Detect source dependencies automatically is set, Model RealTime will automatically detect if there are any elements that need to be included in the build, but that are not listed as source elements neither in the built TC nor in its prerequisites. When an executable TC is built, this analysis starts from the specified top capsule and any elements present in the Sources list. All elements that are referenced by these elements, directly or indirectly, will be automatically included in the build. This means that you can leave the Sources list empty for an executable TC and let Model RealTime automatically compute the source elements that need to be built.

When you build a library TC, there is no top capsule, and in that case the Sources list must contain at least one element which the reference analysis can start from.

Note that an automatically added source element will be built by the same TC that builds the element that references it. If the built TC and its prerequisites specify different build settings, this can lead to that automatically included source elements get built with incorrect build settings. Therefore, the model compiler will print a warning in this case:

16:04:33 : WARNING : Found elements which are not included as source into any TC, some of them could have been added into wrong context

You can ignore this warning if you know that it doesn't matter into which TC the missing elements are included.

It's important that all users who build a model agree on if the "Detect source dependencies automatically" preference should be set or not. When it is used you can no longer look at the Sources list of a TC to understand which elements that will be transformed when the TC is built. Also note that when this preference is set, it\'s solely the references from elements in the built TC that determines which elements that need to be built. The source elements of prerequisite TCs will be included in the build, but their references will not be analyzed. It\'s very important that references in the model are correctly set-up, so they are bound to the expected model elements. If you find that unexpected model elements get transformed when using this feature, you can turn on the preference RealTime Development -- Build/Transformations -- C++ -- Report details about automatically added source elements. Then messages will be printed about which elements that are considered necessary to transform, and why.

One way to use the "Detect source dependencies automatically" feature is to have it enabled, but anyway update the TC Sources list with the elements that are reported as missing. The model compiler prints a summary message of all elements it found to be referenced, but that are not listed as source elements in the TC or its prerequisites. This message is on a format that makes it possible to directly copy and paste it into the Code tab in the TC editor to update the Sources list conveniently. There are two benefits with taking the extra time to update the Sources list:

Here is an example of what this message can look like:

07:54:38 : INFO : Adding missing sources on-the-fly to
\"MyProj/HelloWorld.tcjs\" :
\'platform:/resource/MyProj/HelloWorld.emx#\_s1xKwPoYEemJs6K8xfurHQ\'
/\* HelloWorld::HelloWorld \*/,
\'platform:/resource/MyProj/HelloWorld.emx#\_utwnIPoYEemJs6K8xfurHQ\'
/\* HelloWorld::MyClass \*/

Context Sensitive Library Builds

It is common that the source elements of a TC with prerequisite libraries only reference a small subset of all elements that are available in those libraries. This is because a library is typically designed for being used in many different contexts (executables and/or other libraries) and in each such context only some limited part of the library is used. For example, consider the situation when a library TC is the prerequisite of two different TCs A and B:

The source elements of A only reference some parts of the library (marked in green above), while the source elements of B reference a different subset of the library (marked in blue above).

By default a library TC is built into a library which contains all its source elements. All executables and libraries which have that library as a prerequisite can then link with it. However, if the library is big, and you only want to build one particular TC that uses it, the time it takes to transform and compile source elements that are not referenced is actually wasted.

To address this problem, Model RealTime supports a feature called "Context sensitive library builds". It is controlled by a preference RealTime Development -- Build/Transformations -- C++ -- Context sensitive library builds. It is based on analyzing which elements that are actually referenced by the source elements of the TC that is built. All elements from prerequisite TCs that are referenced will be transformed and built into object files. These object files are then put together into a library which is linked with the executable or library that corresponds to the top-level TC that is built.

This means that the result of building a library TC will be different depending on how it is built:

If you only want to build some TCs in a context sensitive way, you can set a TC property called "Context sensitive library build". The property applies for the TC itself and also for all its prerequisite libraries.

The \"Context sensitive library build\" feature can be combined with \"Detect source dependencies automatically\". In that case source elements of prerequisite TCs will only be included in the build of the library if they are referenced by an element in the built TC, and missing source elements will be automatically added.

Automated Source Management and External Code

The strategies for automating the management of TC source elements described above all relies on correct references in the model, since that is what is used for determining what gets built. If you have external C++ code that references model elements, you must therefore make sure that these references are formally represented as dependencies in the model. Otherwise the build may skip those referenced elements, which will lead to build errors. The recommended way to include external code that references model elements is to use artifacts, since you then can use regular dependencies on the artifact to represent the references to other elements that exist in the code. However, if you have external code outside of the model that contains references to code generated from the model, then you can follow the steps outlined below:

  1. Create a special class in the model that contains the elements that are referenced from external C++ code. Open the Properties view and go to the "C++ General" section. Set "Generate files" to Header so that only a header file gets generated for this class.

  2. For this special class add dependencies to all UML model elements that are referenced by external code.

  3. Finally create dependencies to this special class from all elements of the model that are referenced from other models. This ensures that whenever you build those other models, the model elements that are referenced from the external code will also be included into the build.