Overriding TargetRTS functions in a model
May 04, 2020
Did you know that it's possible to override a certain function from the TargetRTS in a model? This may be useful in some cases where you want to customize the behavior of the TargetRTS for only one specific model. In that case it may be easier to just override one or a few functions from the TargetRTS instead of creating your own specific copy of the TargetRTS.
As an example, assume you have a model that uses the Log service from the TargetRTS, but now you want to turn off all logging. Rather than finding all the many places where the Log service is used in the model and change them, we can simply just override a few of the Log functions to disable all logging.
- First we create an Artifact in the model. Name it as you like, for example "Log_Override".
- Make sure the created artifact is included as a source element of the TC. Either directly, or indirectly as contained in a source element (such as the top package).
- Double-click the artifact to open the Code Editor. Write empty implementations for the four functions from the Log service that are involved when printing log messages to stderr:
void Log::Base::show( const void * value, const RTObject_class * type )
{
}
void Log::Base::show( const char * str )
{
}
void Log::Base::commit( void )
{
}
void Log::Base::crtab( int i )
{
}
- Build your application TC.
If you now get link errors ("multiple defined symbols"), it means the linker was unabled to replace the functions from the TargetRTS with your new empty functions. There can be a few different reasons for this:
- When multiple object files contain the same symbols, we want the artifact object file, which comes first in the link command, to be used. Some linkers automatically resolve conflicts by picking the symbols from the object file that comes first in the link command, while others may require an explicit link argument for doing so. For example, the ld command often used with gcc has a special argument for this. Set the TC property "Compile arguments" to
-Xlinker -z -Xlinker multidefs
to pass this argument to the linker.
- If the TargetRTS has been built with the flag "Build flat" then object files are built per class rather than per function. This speeds up the build of the TargetRTS since less source files need to be compiled, but it also means you no longer can override individual functions from the TargetRTS. If you build your TargetRTS using the TargetRTS wizard, make sure the "Build Flat" checkbox is not marked:
- Overriding TargetRTS functions will not work if you have customized the link order (in the TC or in the preferences) so that the TargetRTS object files do not come after the object files generated from the model.