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
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.
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
Specify additional dependencies with the
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.
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.
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
#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.
Several locations in the MATLAB® folder tree contain static file dependencies specific to the code generator:
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
Header files in the folder
Header files in the folder
These folders contain additional header file dependencies such as
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
Blockset products with S-function code apply the
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
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
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
-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
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.
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.
make command to specify a
USER_INCLUDES make variable that defines a folder in which the
build process searches for included files. For example:
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.
#includeStatements 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:
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
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
cc -Ic:\work ...
When using the build process, avoid dependencies on folders in the build process Code generation folder, such as the
folder or the
slprj folder. Do not use paths in
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
source file into a
subfolder such as:
#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.