Main Content

Add Build Process Dependencies

When you specify a system target file for code generation, the code generator can build a standalone executable program that can run on the development computer. To build the executable program, the code generator uses the selected compiler and the makefile generated by the toolchain or template makefile (TMF) build process approach. Part of the makefile generation process is to add source file, header file, and library file information (the dependencies) in the generated makefile for a compilation. Or, for a specific application, you can add the generated files and file dependencies through a configuration management system.

The generated code for a model consists of a small set of files. (See Manage Build Process Files.) These files have dependencies on other files, which occur due to:

  • Header file inclusions

  • Macro declarations

  • Function calls

  • Variable declarations

The model or external code introduces dependencies for various reasons:

  • Blocks in a model generate code that makes function calls. These calls can occur in several forms:

    • Included source files (not generated) declare the called functions. In cases such as a blockset, manage these source file dependencies by compiling them into a library file.

    • The generated code makes calls to functions in the run-time library provided by the compiler.

    • Some function dependencies also are generated files, which are referred to as shared utilities. Some examples are fixed-point utilities and non-finite support functions. These dependencies are referred to as shared utilities. The generated functions can appear in files in the build folder for standalone models or in the _sharedutils folder under the slprj folder for builds that involve model reference.

  • Models with continuous time require solver source code files.

  • Code generator options such as external mode, C API, and MAT-file logging.

  • External code specifies dependencies.

File Dependency Information for the Build Process

The code generator provides several mechanisms to input file dependency information into the build process. The mechanisms depend on whether your dependencies are block-based or are model- or system target file-based.

For block dependencies, consider using:

  • S-functions and blocksets

    • Add folders that contain S-function MEX-files that the model uses to the header include path.

    • Create makefile rules for these folders to allow for finding source code.

    • Specify additional source file names with the S-Function block parameter SFunctionModules.

    • Specify additional dependencies with the rtwmakecfg.m mechanism. See Use rtwmakecfg.m API to Customize Generated Makefiles.

    For more information on applying these approaches to legacy or external code integration, see Import Calls to External Code into Generated Code with Legacy Code Tool.

  • S-Function Builder block, which provides its own UI for specifying dependency information

For model- or system target file-based dependencies, such as external header files, consider using:

  • The Code Generation > Custom Code pane in the Configuration Parameters dialog box. You can specify additional libraries, source files, and include folders.

  • TLC functions LibAddToCommonIncludes() and LibAddToModelSources(). You can specify dependencies during the TLC phase. See LibAddToCommonIncludes(incFileName) and LibAddSourceFileCustomSection(file, builtInSection, newSection). The Embedded Coder® product also provides a TLC-based customization template for generating additional source files.

Generated Makefile Dependencies

For toolchain approach or template makefile (TMF) approach build processes, the code generator generates a makefile. For TMFs, the generated makefile provides token expansion in which the build process expands different tokens in the makefile to include the additional dependency information. The resulting makefile contains the complete dependency information. See Customize Template Makefiles.

The generated makefile contains:

  • Names of the source file dependencies

  • Folders where source files are located

  • Location of the header files

  • Precompiled library dependencies

  • Libraries that the make utility compiles and creates

A property of make utilities is that you do not have to specify the specific location for a given source C or C++ file. If a rule exists for that folder and the source file name is a prerequisite in the makefile, the make utility can find the source file and compile it. The C or C++ compiler (preprocessor) does not require absolute paths to the headers. The compiler finds header file with the name of the header file by using an #include directive and an include path. The generated C or C++ source code depends on this standard compiler capability.

Libraries are created and linked against, but occlude the specific functions that the program calls.

These properties can make it difficult to determine the minimum list of file dependencies manually. You can use the makefile as a starting point to determine the dependencies in the generated code.

Another approach to determining the dependencies is using linker information, such as a linker map file, to determine the symbol dependencies. The map file provides the location of code generator and blockset source and header files to help in locating the dependencies.

Code Generator Static File Dependencies

Several locations in the MATLAB® folder tree contain static file dependencies specific to the code generator:

  • matlabroot/rtw/c/src (open)

    This folder has subfolders and contains additional files must be compiled. Examples include solver functions (for continuous time support), external mode support files, C API support files, and S-function support files. Include source files in this folder into the build process with the SRC variables of the makefile.

  • Header files in the folder matlabroot/rtw/extern/include

  • Header files in the folder matlabroot/simulink/include

    These folders contain additional header file dependencies such as tmwtypes.h, simstruc_types.h, and simstruc.h.

    Note

    For ERT-based system target files, you can avoid several header dependencies. ERT-based system target files generate the minimum set of type definitions, macros, and so on, in the file rtwtypes.h.

Blockset Static File Dependencies

Blockset products with S-function code apply the rtwmakecfg.m mechanism to provide the code generator with dependency information. The rtwmakecfg.m file from the blockset contains the list of include path and source path dependencies for the blockset. Typically, blocksets create a library from the source files to which the generated model code can link. The libraries are created and identified when you use the rtwmakecfg.m mechanism.

To locate the rtwmakecfg.m files for blocksets in your MATLAB installed tree, use the following command:

>> which -all rtwmakecfg.m

If the model that you are compiling uses one or more of the blocksets listed by the which command, you can determine folder and file dependency information from the respective rtwmakecfg.m file.

Folder Dependency Information for the Build Process

You can add #include statements to generated code. Such references can come from several sources, including TLC scripts for inlining S-functions, custom storage classes, bus objects, and data type objects. The included files consist of header files for external code or other customizations. You can specify compiler include paths with the -I compiler option. The build process uses the specified paths to search for included header files.

Usage scenarios for the generated code include, but are not limited to, the following:

  • A custom build process compiles generated code that requires an environment-specific set of #include statements.

    In this scenario, the build process invokes the code generator when you select model configuration parameter Generate code only. Consider using fully qualified paths, relative paths, or just the header file names in the #include statements. Use include paths.

  • The build process compiles the generated code.

    In this case, you can specify compiler include paths (-I) for the build process in several ways:

    • Specify additional include paths on the Code Generation > Custom Code pane in the Configuration Parameters dialog box. The code generator propagates the include paths into the generated makefile.

    • The rtwmakecfg.m mechanism allows S-functions to introduce additional include paths into the build process. The code generator propagates the include paths into the generated makefile.

    • When building a model that uses a custom system target file and is makefile-based, you can directly add the include paths into the template makefile that the system target file uses.

    • Use the make command to specify a USER_INCLUDES make variable that defines a folder in which the build process searches for included files. For example:

      make_rtw USER_INCLUDES=-Id:\work\feature1

      The build process passes the custom includes to the command-line invocation of the make utility, which adds them to the overall flags passed to the compiler.

Use #include Statements and Include Paths

Consider the following approaches for using #include statements and include paths with the build process to generate code that remains portable and minimizes compatibility problems with future versions.

Assume that additional header files are:

c:\work\feature1\foo.h
c:\work\feature2\bar.h
  • An approach is to include in the #include statements only the file name, such as:

    #include "foo.h"
    #include "bar.h"

    Then, the include path passed to the compiler contains folders in which the headers files exist:

    cc -Ic:\work\feature1 -Ic:\work\feature2     ...
  • Another approach is to use relative paths in #include statements and provide an anchor folder for these relative paths using an include path, for example:

    #include "feature1\foo.h"
    #include "feature2\bar.h"

Then, specify the anchor folder (for example \work) to the compiler:

 cc -Ic:\work   ...

Avoid These Folder Dependencies

When using the build process, avoid dependencies on folders in the build process Code generation folder, such as the model_ert_rtw folder or the slprj folder. Do not use paths in #include statements that are relative to the location of the generated source file. For example, if your MATLAB code generation folder is c:\work, the build process generates the model.c source file into a subfolder such as:

c:\work\model_ert_rtw\model.c

The model.c file has #include statements of the form:

#include "..\feature1\foo.h"
#include "..\feature2\bar.h"

It is preferable to use one of the other suggested approaches because the relative path creates a dependency on the code generator folder structure.

Related Topics