# System definition .sdef

Source: [https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_sdef.html](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_sdef.html)

This topic provides details about TelAF's System Definition files.

`.sdef` files can contain these sections:

## Search Paths

These sections are used to specify directories in which `mksys` should look for the various files that make up your system.

Note: `mksys` allows the command line arguments `-i` or `--interface-search` to also specify the interface search path(s). For backwards compatability, all other search paths fall under the command line arguments `-s` or `--source-search`. To add multiple search paths simply add multiple instances of `-i` or `-s` to your command.

When building `systems` that are intended to be inherited by other projects it is recommended to use the search paths within your included .sdef file. This way each individual subsystem can be added to a top level .sdef file without forcing the user to append many search paths to their command line when running `mksys`.

## interfaceSearch

The interface search is used to find the .api files referenced in your system, your applications, and the components that make up your applications.

To allow components to be relocated in the build host file system, components should not specify interface file search paths outside of their own directories. To separate interfaces from implementation, interfaces should be kept outside of components. This can be accomplished by adding interface search directory paths to the `interfaceSearch` section in the .sdef file.

This way components can be kept in a components directory, and interfaces can be kept within an interface directory. Keeping these API files seperated from compoents can make it easier to share between clients and servers, as well as between seperate server implementations.

So, for example, in a TelAF system definition there would be a interface search paths setup for the APIs offered by TelAF itself under `default.sdef:`

    interfaceSearch:
    {
        $TELAF_ROOT/interfaces                 // Directory contianing
        $TELAF_ROOT/interfaces/modemServices   // Directory containing 
                                               // TelAF modem services 
                                               // APIs.
    }Copy to clipboard

In your sdef, after defining TELAF\_ROOT you can include TelAF's search paths and append your own.

    #include "$TELAF_ROOT/default.sdef"
    
    interfaceSearch:
    {
        $CURDIR/interfaces   // Directory containing custom interfaces belonging 
                             // to this system.
    }Copy to clipboard

Now your components and applications can find all of your custom APIs as well as those that come with TelAF.

          - Note

              - `CURDIR` is a mktools managed variable. `CURDIR` always refers to the directory that your .def file is residing in. So, if your def file is in `~/myProject/mySystem.sdef` then `CURDIR` would be the full path to the def's directory: `/home/username/myProject/` See [Environment Variables](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_format.html#concept.def_files_format__section_add_h35_v5b) for more details on the automatic variables.

For example, inside of one of your `Component.cdef` files:

    requires:
    {
        api:
        {
            taf_sms.api       // Make use of one of the TelAF SMS service APIs.
            myCustomApi.api   // Also, make use of your own custom APIs.
        }
    }Copy to clipboard

## appSearch

This search path is used when specifiing **apps** in your .sdef's `apps:` section. Instead of having to specify a full path to your applications, you can specify locations for where they should be found.

    appSearch:
    {
        $CURDIR/applications  // Search for apps in a subdirectory of the  
                              // directory that holds your .sdef or .sinc 
                              // file.
    }Copy to clipboard

## componentSearch

Use the `componentSearch` to add your paths to the directories that the build system uses to find your components.

    componentSearch:
    {
        $CURDIR/components  // Search for components in a subdirectory of the  
                            // directory that holds your .sdef or .sinc file.
    }Copy to clipboard

This way, when you are defining your applications executables within an `executables:` section you do not need to specify the full path to your component's executables. For example, your application executable is composed of two components, `mainComp` and `helperComp`. Using a component search path, you can easily share helperComp between different executables and different applications.

    executables:
    {
        myExe = ( mainComp helperComp )
    }Copy to clipboard

## moduleSearch

The section `moduleSearch` is for adding to the module search path. This search path is used when specifing **modules** in your .sdef's `kernelModules:` section. Instead of having to specify a full path to your kernel modules, you can specify locations for where they should be found.

For example:

    moduleSearch:
    {
        $TELAF_ROOT/drivers/example  // My example modules are found in this directory.
    }
    
    // In the kernel modules section, you no longer need to give a full path 
    // to your mdef files. The mktools will search through all of your paths 
    // given in the moduleSearch section.
    
    kernelModules:
    {
        example.mdef  // Include my sample module in the build.
    }Copy to clipboard

## apps

An `apps:` section declares one or more apps to be deployed to the target system.

    apps:
    {
        webserver
    }Copy to clipboard

This looks for an app definition file called `webserver.adef` and includes it in the system. You can also optionally include the .adef extension.

Alternatively you can include the full path and adef extension on the declaration and bypass the app search paths.

    apps:
    {
        /full/path/to/my/app/webserver.adef
    }Copy to clipboard

In addition to including applications in source for to your system builds. You can also add binary application packages.

Binary app packages are apps distributed without their source code. You include these apps in your .sdef file `apps:` section just like .adef files.

    apps:
    {
        webserver.sa515m.app
    }Copy to clipboard

Binary app files are named for the target architecture they are built against. This way it's hard to mix up builds for incompatible target architectures. The same pathing and search rules apply to binary apps as do for .adef files.

The `apps:` section can override limits and other app settings.

Here's a code sample to deploy a web server limiting its share of the CPU under heavy load to 500 (see [cpuShare](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_zxb_p45_v5b)):

    apps:
    {
        webServer
        {
            cpuShare: 500
        }
    }Copy to clipboard

Any of the following subsections can be used in an .sdef `apps:` section, and will override the .adef setting for all processes in that app:

- [cpuShare](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_zxb_p45_v5b)
- [faultAction](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_fzb_p45_v5b)
- [groups](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_fyb_p45_v5b)
- [maxCoreDumpFileBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_mzb_p45_v5b)
- [maxFileBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pzb_p45_v5b)
- [maxFileDescriptors](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_szb_p45_v5b)
- [maxFileSystemBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_hyb_p45_v5b)
- [maxLockedMemoryBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_uzb_p45_v5b)
- [maxMemoryBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_lyb_p45_v5b)
- defFilesAdef\_maxMQueueBytes
- [maxPriority](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_sdef.html#concept.def_files_sdef__section_xvz_4m5_v5b)
- [maxQueuedSignals](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_oyb_p45_v5b)
- [maxThreads](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_qyb_p45_v5b)
- [maxSecureStorage Bytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_tyb_p45_v5b)
- [sandboxed](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_ccc_p45_v5b)
- [start](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_fcc_p45_v5b)
- [watchdogAction](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pcc_p45_v5b)
- [watchdogTimeout](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_rcc_p45_v5b)
- [maxWatchdogTimeout](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_ucc_p45_v5b)

## maxPriority

Sets the maximum priority level the app it permitted to use.

Acts as a ceiling only. Lowers the priority level if an app would otherwise be allowed to use a higher priority. It won't raise the priority level for any processes in the app.

Here's a code sample where a process in the app's .adef is configured to start at high priority, and the .sdef section for that app has maxPriority set to `medium` so the process will start at medium priority.

    apps:
    {
        foo
        {
            maxPriority: high
        }
    }Copy to clipboard

Another process in the same .adef configured to start at low priority will still start at low priority.

## preloaded

Indicates whether or not an app must be preloaded onto the target device separately from the rest of the system.

If you are not sure whether or not you need this feature, you probably don't. Use of this feature is intended for very specific use cases. It is encouraged that delta updates of systems be used instead, whenever practical.

TelAF supports being installed in a read-only partition, mounted as `/mnt/legato` in the target file system. Writeable files will be kept in another file system mounted as `/legato` in the target file system.

If the read-only partition must be updated, but there are other (possibly very large) apps in the writeable file system, it may be impossible to deliver an update containing the apps over-the-air at the same time that the read-only partition is updated.

Usually, the read-only partition does not need to be updated, but in some cases, it may be desireable, and this feature can help.

For example, a customer has a giant app containing pictures and audio files. In the factory, the framework and a few apps are loaded into the read-only `/mnt/legato`, and other apps, including the huge app, are installed in the writeable `/legato`. Later, when the device is in the field, a change needs to be made to both the modem firmware and the TelAF framework, and must be delivered together, as a single FOTA (firmware over the air) update. A new system is built using `mksys`. But, the resulting system update file is too large to fit in the FOTA update image (and likely very expensive to deliver over the air to hundreds of thousands of devices). Fortunately, the audio files don't need to be updated at the same time, and the audio app can be marked "preloaded" in the .sdef file to exclude it from the system update file. After the FOTA update, the new system will use the audio file that already exists on the target's writeable file system.

There are 3 different preloaded flag types and each controls the behavior of the MD5 hash compatibility check:

- `buildVersion`
- Explicitly specified MD5 hash
- `anyVersion`

          - Warning

              - Use `preloaded` flag at your own risk! If the preloaded app does not exist on the target, or if it is incompatible (on API or binary level) with new TelAF, then the system may become unstable or even unusable!

## preloaded: buildVersion

Use in the case when the app version installed on the target, matches the most recent source code (in your build environment). That means the MD5 hash generated by the build, will match the MD5 hash of the application installed on the target. "Build version" refers to the MD5 hash of the app, not the [version](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_lcc_p45_v5b) tag specified in the application definition (.adef) file.

    apps:
    {
        modemService
        audioService
        dataConnectionService
        controller
        userInterface { preloaded: buildVersion }
    }Copy to clipboard

After you have built the new system, verify that the app that was marked "preloaded" in the .sdef file has the same MD5 hash as the app that is actually installed on the target. You can do this by comparing the contents of the symlink in `/legato/systems/current/apps/` on the target with the contents of the symlink in the `_staging_system.sa515m.update_ro/apps/` directory of the system's build directory on the build host.

    $ readlink /legato/systems/current/apps/userInterface // Run this command on the device
    /legato/apps/a60357d912ff3b4b28e080580b34fff3
    $ readlink build/sa515m/_staging_system.sa515m.update_ro/apps/userInterface
    /legato/apps/a60357d912ff3b4b28e080580b34fff3Copy to clipboard

If these are different, then something has changed that has resulted in the built version of your app to be different in the context of your new system. If you continue to install your new system on the target, the "preloaded" app will not start.

Note: Option `{preloaded: buildVersion}` is equivalent to the existing option `{preloaded: true}`, which is now deprecated.

## preloaded: "MD5 hash"

    apps:
    {
        modemService
        audioService
        dataConnectionService
        controller
        userInterface { preloaded: a60357d912ff3b4b28e080580b34fff3 }
    }Copy to clipboard

If the MD5 hash of your app (in your build environment) is different from what is installed on the target and you want to use the hash from the target, you can set the `preloaded:` option to the MD5 hash of your build environment. You must manually check that this version of the app is still compatible with your new system. This will ensure that the app is **NOT** replaced when the system is loaded on your target. Change the "buildVersion" in your "preloaded: " statement in your .sdef file to the MD5 hash of the old version of the app installed on your target.

## preloaded: anyVersion

    apps:
    {
        modemService
        audioService
        dataConnectionService
        controller
        userInterface { preloaded: anyVersion }
    }Copy to clipboard

This option allows you to re-use the preloaded app which has MD5 hash different from the app in your build environment, but without explicitly specifying the MD5 hash in the .sdef file. Essentially, you are telling the system to re-use whatever version of the app is currently installed on the target.

This option is convenient if you want to re-use the same update image for multiple targets, and these targets may have different versions (i.e. different MD5 hash) of this app already installed. In this use case, you can specify "anyVersion" option for the preloaded flag. During the system update the installer will find an app with the same name that was installed previously (and was part of the previous system), and establish a proper symlink to it. If the app with the given name is not found, it can not be started.

Note: You have to be absolutely certain that the version of the preloaded app that is installed on any of your targets, is still compatible with the new system you are about to install.

## bindings

Lists IPC `bindings` that connect apps’ external IPC interfaces. They're listed in the [extern section of their .adef files](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_e1c_p45_v5b). Each binding connects one client-side interface to one server-side interface.

Interfaces use the app name and the interface name, separated by a period (‘.’). The two bound-together interfaces are separated by an arrow ("-&gt;").

For example,

    apps:
    {
        vavController
        thermostat
        airHandlerProxy
    } 
    bindings:
    {
        // Connect the VAV controller to the thermostat    vavController.temp -> thermostat.temp
        vavController.setpoint -> thermostat.setpoint         //< Connect the VAV
                                                              // controller to the
                                                              // supply air duct 
                                                              // temperature sensor    vavController.ductTemp -> ductTemperatureSensor.temp  //< Hook up the VAV 
                                                              //  control outputs 
                                                              //  to the damper 
                                                              //  actuators.
        vavController.supplyDamper -> supplyAirDamper.damper
        vavController.returnDamper -> returnAirDamper.damper  //< Use a network proxy
                                                              //  to request duct 
                                                              //  temperature changes 
                                                              //  from the Air Handling
                                                              //  Unit.    vavController.airHandler -> airHandlerProxy.airHandler
    }Copy to clipboard

For security reasons, binding between apps is never performed unless explicitly specified in the .sdef or .adef files.

## buildVars

Build environment variables can be defined inside the .sdef file using "buildVars:" sections. This will define variables in the build tools' process environment at build time.

    buildVars:
    {
        PRODUCT_VERSION = "0.2.3 - beta"
        HARDWARE_REV = 4
    }Copy to clipboard

These are defined using "name = value" pairs, where the value can be a quoted string and may contain the values of other environment variables that were previously defined.

All `buildVars:` sections will be evaluated before processing any other sections. So, even if a `buildVars:` section appears after another section that uses it, the variables will be available in that other section.

Note: This is necessary to allow the sharing of components between apps. If two apps contained the same component, but each app were built with a different set of environment variables, it would be hard to tell which set of environment variables were used to build the shared component, and the component may behave in an unexpected way for one of the apps.

    apps:
    {
        $APP_PATH
    }
    
    buildVars:
    {
        APP_PATH = path/to/app
    }Copy to clipboard

Within the `buildVars:` sections, the order of the definitions matters.

    buildVars:
    {
        X = foo  // X is now "foo"
    
        X = bar  // X has been changed to "bar"
    
        X = foo${X}  // X has been changed to "foobar"
    
        X = "$X baz" // X has been changed to "foobar baz"
    }Copy to clipboard

## cflags

Provides a way to specify command-line arguments to pass to the compiler when compiling C source code files. These flags will be added to the flags specified on the command-line and in other definition files.

Flags are separated by whitespace.

    cflags:
    {
        -g -O0
        -DDEBUG=1
    }Copy to clipboard

## cxxflags

Provides a way to specify command-line arguments to pass to the compiler when compiling C++ source code files. These flags will be added to the flags specified on the command-line and in other definition files.

Flags are separated by whitespace.

    cxxflags:
    {
        -std=c++0x
        -g -O0
    }Copy to clipboard

## ldflags

Linker flags provide a way to specify command-line arguments to pass to the compiler when linking C/C++ object (.o) files together into a component shared library (.so) file. These flags will be added to the flags specified on the command-line and in other definition files.

Flags are separated by whitespace.

    ldflags:
    {
        -Lfoo/bar
    }Copy to clipboard

## kernelModules

The optional `kernelModules:` section declares a list of kernel modules to be bundled and installed with TelAF.

Each entry represents a path to the [.mdef](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_mdef.html) definition file that describes how the module is installed on the target.

This code sample shows the section declaring the "/path/to/kernel/module/hello.mdef" be bundled with TelAF:

    kernelModules:
    {
        /path/to/kernel/module/hello
        /path/to/kernel/module/world [optional]
    }Copy to clipboard

The kernel modules listed in this section are loaded in alphabetical order and removed in reverse alphabetical order by the TelAF system. If a module depends on one or more other modules, then the order in which the modules are installed and removed takes the dependencies into consideration. Dependencies are added by adding the modules to the `requires:` `kernelModules:` section of the [.mdef](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_mdef.html) for the kernel module that depends on them.

Note: In case a module fails to load, the fault handler kicks in which restarts the TelAF framework in order to attempt the recovery of the system. If the framework does not need to be restarted when a module fails to load, the module must be marked as optional by using '[optional]' tag. In the above example, world is an optional module.

## commands

To make a command-line tool available to a root user who is logged-in to a shell on a target device tty (e.g., through secure shell [ssh] or a serial console):

1. Build an app containing the executable.
2. Add the executable to the "commands:" section of the .sdef file.

Each entry in the commands section looks like this:

    commandName = appName:/path/to/exeCopy to clipboard

The path to the executable must be an absolute path within the application's read-only installed files. For example, if the executable is a script that was bundled into the app "myApp" to appear at "/usr/share/exe" inside the myApp's sandbox at runtime, then the command would be specified as

    commandName = myApp:/usr/share/exeCopy to clipboard

If the executable is built using an "executables" section in a .adef file, then the executable will appear in the app's bin directory. For example,

    apps:
    {
        myTools // This app's .adef builds an exe called "led" that can be used 
                // to turn LEDs on and off.
    } 
    commands:
    {
        led = myTools:/bin/led  // When I login via ssh, I can run "led 1 on" 
                                // to turn on LED 1.
    }Copy to clipboard

Warning: When the command runs, it runs with the full privileges of the user that runs it. If you login as root and run a command, the command executes with root user privileges.

## externalWatchdogKick

If your system is hooked up to an external watchdog (e.g.; SA515M is externally hooked up to Linux's Softdog) the internal watchdog daemon will "kick" the external watchdog at a specified time as long as all watched processes and apps are running and have successfully "kicked" the internal watchdog.

The externalWatchdogKick sets the interval for the internal watchdog daemon to kick the external watchdog. If no external watchdog exists then externalWatchdogKick will have no effect on the system.

If this section is not specified then the **default of 30 seconds** will be used.

Example:

    externalWatchdogKick: 120000 // Configure external watchdog kick to 2minsCopy to clipboard

## extern

Externs indicate which of your system's RPC API interfaces should be made available for binding to the RPC API interfaces of other systems.

For example,

    extern:
    {
        aliasName = appName.interfaceName
    }Copy to clipboard

This creates an alias for each interface that doesn't include any internal implementation details of your system.

Inside your system, its network-interfaces are identified using the names of the executables and components that implement them. Exposing these details outside your system can create maintainability problems later (see [https://en.wikipedia.org/wiki/Information_hiding](https://en.wikipedia.org/wiki/Information_hiding)).

Externally, the network-interface will be identified using the system name and the external alias (`systemName.aliasName`), thereby hiding from other systems the details of which executable and component implements the interface. Encapsulating the system's implementation details allows them to be changed later without affecting other systems that communicate with this system. Only if a system's external interface changes would any other system be affected.

Use period characters ('.') to seperate components of a network-interface. (E.g., applications and interface names.) External aliases must not contain any period characters ('.').

When the external alias has the same name that the component uses as the interface name, it's possible to save time by omitting the `aliasName =` part. For example,

    extern:
    {
        appName.interfaceName
    }Copy to clipboard

This is equivalent to

    extern:
    {
        interfaceName = appName.interfaceName
    }Copy to clipboard

To use this extern feature, RPC must be enabled when building the TelAF framework.

## links

The `links:` section declares a list of network communication links to be bundled and installed with TelAF, as a part of supporting TelAF APIs [API Files](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files.html) across multiple remote-host systems that are networked together (i.e. inter-system (RPC) communication).

Each entry identifies a component definition and an optional list of command-line arguments, used to declare run-time parameters for creating/opening a communication channel to a specific remote-host system, such as IP address, listening port number, baud rate, etc..

Format:

    linkName = (<componentName>, "arg1", "arg2", ...)Copy to clipboard

The component definition file provides the le\_comm.h implementation of the RPC communication channel for a system, and is required in order for remote system communication to be established during system run-time. The TelAF RPC communication API, le\_comm.h, provides a standard interface for facilitating all system-to-system network-layer communication.

For example,

    links:
    {
        LINK1 = (networkSocket "10.0.0.5" "54323")
    }Copy to clipboard

This looks for a component definition file Component.cdef ([.cdef Files](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files.html#concept.def_files__defFilesOverview_cdef)) in a components directory called `networkSocket` and includes it in the system.

Alternatively you can include the full path on the declaration and bypass the system componentDirs search paths.

    links:
    {
        LINK1 = (/full/path/to/my/network/networkSocket "10.0.0.5" "54323")
    }Copy to clipboard

To use the links feature, RPC must be enabled when building the TelAF framework.

**Parent Topic:** [Definition files](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files.html)

Last Published: Apr 23, 2025

[Previous Topic
def files format](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/def_files_format.md) [Next Topic
Application definition .adef](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/def_files_adef.md)