Define Custom Makefile-Based Toolchains Using Target Framework
To build code that you generate from Simulink® models, you can specify a shipped makefile-based toolchain definition – see Toolchain Approach. Using the Target Framework, you can define and register custom makefile-based toolchains. This topic provides toolchain definition examples that you can adapt to build code for your target hardware.
Overview of Makefile-Based Toolchain Definition
To define a toolchain, create a target.Toolchain
object. Use
the object to:
Associate the toolchain with your target hardware.
Specify the platforms on which the toolchain can run.
Provide system environment setup commands and paths for the operating system.
To specify that the toolchain is makefile-based, attach a
target.MakefileBuilder
object to the
Builder
property of the target.Toolchain
object. The target.MakefileBuilder
object specifies the type of
makefile (GNU® Make or NMAKE) that the software generates.
To specify the tools (assembler, compiler, linker, etc) for the toolchain, use
target.BuildTool
objects. Associate each
target.BuildTool
object with a predefined
target.BuildToolType
object that specifies the directives and
file types that the target.BuildTool
object must define. If you
specify the name of the target.BuildToolType
when creating
target.BuildTool
, the software uses default GCC values for
directives and file types. If you use a toolchain that is not GCC-based, you must
update the prepopulated directives and file-type settings with values for the
toolchain.
When you add the target.Toolchain
object to the internal
database, the software uses specifications in the
target.BuildToolType
objects to check that:
Directive names are valid and the directives have a specification.
Names for valid file types are associated with file extensions, and the required file extensions are set.
For each target.BuildTool
object, you can use the
showDirectives
and showFileExtensions
methods to visualize the build tool configuration.
Define GCC-Based Toolchain for Windows Development Computer
Create a
target.Toolchain
object and specify the operating system.mingwtc = target.create('Toolchain', ... 'Name', 'Example MinGW Toolchain', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly);
Place the binary files folder of the MinGW® toolchain on the system search path.
mingwtc.EnvironmentConfiguration.SystemPaths{end+1} = '$(MW_MINGW64_LOC)/bin';
Associate the toolchain with the target hardware, which is your Windows® development computer.
mingwtc.SupportedHardware = target.create('HardwareComponentSupport', ... 'Component', target.get('Processor', 'Intel-x86-64 (Windows64)'));
Specify that the toolchain is based on a GNU Make makefile.
mingwtc.Builder = target.create('MakefileBuilder', 'GMake');
Specify the assembler.
assembler = target.create('BuildTool', 'Assembler', 'as', ... 'Name', 'GNU Assembler'); mingwtc.Tools(end+1) = assembler;
For the Windows operating system, specify C and C++ compilers that use command files and generate object files with the
.obj
extension.cCompiler = target.create('BuildTool', 'C Compiler', 'gcc', ... 'Name', 'MinGW GCC C Compiler'); cCompiler.setDirective('CommandFile', '@'); cCompiler.setFileExtensions('Object', {'.obj'}); mingwtc.Tools(end+1) = cCompiler; cppCompiler = target.create('BuildTool', 'C++ Compiler', 'g++', ... 'Name', 'MinGW GCC C++ Compiler'); cppCompiler.setDirective('CommandFile', '@'); cppCompiler.setFileExtensions('Object', {'.obj'}); mingwtc.Tools(end+1) = cppCompiler;
Through directives and file extension settings, specify C and C++ linkers that:
Support the generation of dynamic link libraries (DLLs)
Group libraries that have circular dependencies
Use command files
Create files for Windows
In this example, you create thecLinker = target.create('BuildTool', 'Linker', 'gcc', ... 'Name', 'MinGW Linker', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); cLinker.setDirective('Shared', '-shared -Wl,--out-implib,$(notdir $(basename $(PRODUCT))).lib'); cLinker.setDirective('LibraryGroup', '-Wl,--start-group', '-Wl,--end-group'); cLinker.setDirective('CommandFile', '@'); cLinker.setFileExtensions('Object', {'.obj'}); cLinker.setFileExtensions('Executable', {'.exe'}); cLinker.setFileExtensions('Shared Library', {'.dll'}); mingwtc.Tools(end+1) = cLinker; cppLinker = target.create('BuildTool', 'Copy', cLinker, ... 'Name', 'MinGW C++ Linker', ... 'BuildToolType', target.get('BuildToolType', 'C++ Linker'), ... 'Command', target.create('Command', 'g++')); mingwtc.Tools(end+1) = cppLinker;
cppLinker
object by creating a copy ofcLinker
and modifying properties of the copy.Specify an archiver.
archiver = target.create('BuildTool', 'Archiver', 'ar ruvs', ... 'Name', 'GNU Archiver'); archiver.setFileExtensions('Object', {'.obj'}); mingwtc.Tools(end+1) = archiver;
Specify a
make
tool.Themaketool = target.create('BuildTool', 'Make Tool', 'mingw32-make -j$(NUM_CORES)', ... 'Name', 'MinGW GNU Make', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); mingwtc.Tools(end+1) = maketool;
$(NUM_CORES)
token is expanded to the number of cores on your system, and enables parallel processing of themake
command.Specify basic system tools like
echo
,del
, andmove
, which the makefile uses to display, delete, and move files. The predefinedtarget.Toolset
object contains the tool definitions.basictools = target.get('Toolset', 'Windows system tools for Makefiles'); mingwtc.Tools(end+1) = basictools;
Specify standard dependencies:
C math and Winsock libraries to link with the compiled generated code
Compiler flags that are always passed to the C and C++ compilers
mingwtc.BuildRequirements.SharedLibraries{end+1} = 'm'; mingwtc.BuildRequirements.SharedLibraries{end+1} = 'ws2_32'; mingwtc.BuildRequirements.CompilerFlags{end+1} = '-fwrapv'; mingwtc.BuildRequirements.CompilerFlags{end+1} = '-fPIC'; mingwtc.BuildRequirements.LinkerFlags{end+1} = '-static'; mingwtc.BuildRequirements.LinkerFlags{end+1} = '-m64';
Add the toolchain definition to the internal database.
target.add(mingwtc);
To use the custom toolchain definition for building generated code, in the Configuration Parameters dialog box:
On the Hardware Implementation pane, select your target device by setting Device vendor to
Intel
and Device type tox86-64 (Windows64)
.On the Code Generation pane, from the Toolchain list, select
Example MinGW Toolchain
.Click OK.
When you run, for example, the slbuild
function or a
software-in-the-loop (SIL) simulation, the build process uses the custom toolchain
to build generated code.
If you want to remove the custom toolchain definition from the internal database, run:
customToolChainDef = target.get('Toolchain', 'Example MinGW Toolchain'); target.remove(customToolChainDef);
Define Microsoft Visual Studio Toolchain for Building 32-Bit Application
Create a toolchain object and specify the operating system.
msvctc = target.create('Toolchain', ... 'Name', '32-bit Visual Studio Toolchain', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly);
Create a command that runs
vcvarsall.bat
, which is required to set up environment variables for Microsoft® Visual C++®. This command assumes that Microsoft Visual Studio® 2019 is installed on your development computer. If another version is installed, provide the full path tovcvarsall.bat
.msvctc.EnvironmentConfiguration.SetupCommand = target.create('Command', ... '$(MSVC160_INSTALL_DIR)\VC\Auxiliary\Build\VCVARSALL.BAT x86');
Associate the toolchain with the target hardware, which is your Windows development computer.
msvctc.SupportedHardware = target.create('HardwareComponentSupport', ... 'Component', target.get('Processor', 'Intel-x86-32 (Windows32)'));
Specify that the toolchain is based on an NMAKE makefile.
msvctc.Builder = target.create('MakefileBuilder', 'NMake');
Using
target.BuildTool
objects, specify C and C++ compilers:Update default GCC directives with Microsoft Visual C++ values.
Use command files and generate object files with the
.obj
extension.Specify additional command-line flags that only apply to the C++ compiler.
cCompiler = target.create('BuildTool', 'C Compiler', 'cl', ... 'Name', 'Microsoft Visual C Compiler', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); cCompiler.setDirective('OutputFlag', '-Fo'); cCompiler.setDirective('Debug', '-Zi'); cCompiler.setDirective('EnableOptimization', '/O2 /Oy-'); cCompiler.setDirective('DisableOptimization', '/Od /Oy-'); cCompiler.setDirective('CommandFile', '@'); cCompiler.setFileExtensions('Object', {'.obj'}); msvctc.Tools(end+1) = cCompiler; cppCompiler = target.create('BuildTool', 'C++ Compiler', 'cl -EHs /wd4251 /Zc:__cplusplus', ... 'Name', 'Microsoft Visual C++ Compiler', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); cppCompiler.setDirective('OutputFlag', '-Fo'); cppCompiler.setDirective('Debug', '-Zi'); cppCompiler.setDirective('EnableOptimization', '/O2 /Oy-'); cppCompiler.setDirective('DisableOptimization', '/Od /Oy-'); cppCompiler.setDirective('CommandFile', '@'); cppCompiler.setFileExtensions('Object', {'.obj'}); msvctc.Tools(end+1) = cppCompiler;
Through directives and file extension settings, specify C and C++ linkers.
cLinker = target.create('BuildTool', 'Linker', 'link', ... 'Name', 'Microsoft Visual C Linker', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); cLinker.setDirective('Library', '-L'); cLinker.setDirective('LibrarySearchPath', '/LIBPATH'); cLinker.setDirective('OutputFlag', '-out:'); cLinker.setDirective('Debug', '/DEBUG'); cLinker.setDirective('Shared', '-dll'); % Allow shared library cLinker.setDirective('DefFile', '-def:'); cLinker.setDirective('CommandFile', '@'); cLinker.setFileExtensions('Object', {'.obj'}); cLinker.setFileExtensions('Executable', {'.exe'}); cLinker.setFileExtensions('Shared Library', {'.dll'}); msvctc.Tools(end+1) = cLinker; cppLinker = target.create('BuildTool', 'C++ Linker', 'link', ... 'Name', 'Microsoft Visual C++ Linker', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); cppLinker.setDirective('Library', '-L'); cppLinker.setDirective('LibrarySearchPath', '/LIBPATH'); cppLinker.setDirective('OutputFlag', '-out:'); cppLinker.setDirective('Debug', '/DEBUG /DEBUGTYPE:cv'); cppLinker.setDirective('Shared', '-dll'); % Allow shared library cppLinker.setDirective('DefFile', '-def:'); cppLinker.setDirective('CommandFile', '@'); cppLinker.setFileExtensions('Object', {'.obj'}); cppLinker.setFileExtensions('Executable', {'.exe'}); cppLinker.setFileExtensions('Shared Library', {'.dll'}); msvctc.Tools(end+1) = cppLinker;
Specify an archiver.
archiver = target.create('BuildTool', 'Archiver', 'lib /nologo', ... 'Name', 'Microsoft Visual C/C++ Archiver'); archiver.setDirective('OutputFlag', '-out:'); archiver.setFileExtensions('Object', {'.obj'}); archiver.setFileExtensions('Static Library', {'.lib'}); msvctc.Tools(end+1) = archiver;
Specify a make tool.
maketool = target.create('BuildTool', 'Make Tool', 'nmake', ... 'Name', 'Microsoft NMake', ... 'HostOperatingSystemSupport', target.HostOperatingSystemSupport.WindowsOnly); msvctc.Tools(end+1) = maketool;
Specify basic system tools like
echo
,del
, andmove
, which the makefile uses to display, delete, and move files. The predefinedtarget.Toolset
object contains the tool definitions.basictools = target.get('Toolset', 'Windows system tools for Makefiles'); msvctc.Tools(end+1) = basictools;
Specify standard dependencies:
Libraries to link with the compiled generated code
Preprocessor directives that must be set
Compiler flags that are always passed to the C and C++ compilers
Linker flags
msvctc.BuildRequirements.SharedLibraries{end+1} = 'kernel32.lib'; msvctc.BuildRequirements.SharedLibraries{end+1} = 'ws2_32.lib'; msvctc.BuildRequirements.SharedLibraries{end+1} = 'mswsock.lib'; msvctc.BuildRequirements.SharedLibraries{end+1} = 'advapi32.lib'; msvctc.BuildRequirements.Defines{end+1} = '_CRT_SECURE_NO_WARNINGS'; msvctc.BuildRequirements.Defines{end+1} = 'WIN32'; msvctc.BuildRequirements.Defines{end+1} = '_MT'; msvctc.BuildRequirements.CompilerFlags{end+1} = '-nologo'; msvctc.BuildRequirements.CompilerFlags{end+1} = '-GS'; msvctc.BuildRequirements.CompilerFlags{end+1} = '-W4'; msvctc.BuildRequirements.CompilerFlags{end+1} = '-MT'; msvctc.BuildRequirements.LinkerFlags{end+1} = '/INCREMENTAL:NO'; msvctc.BuildRequirements.LinkerFlags{end+1} = '/NOLOGO';
Add the toolchain definition to the internal database.
target.add(msvctc);
To use the custom toolchain definition for building generated code, in the Configuration Parameters dialog box:
On the Hardware Implementation pane, select your target device by setting Device vendor to
Intel
and Device type tox86-32 (Windows32)
.On the Code Generation pane, from the Toolchain list, select
32-bit Visual Studio Toolchain
.Click OK.
When you run, for example, the slbuild
function or a
software-in-the-loop (SIL) simulation, the build process uses the custom toolchain
to build generated code.
If you want to remove the custom toolchain definition from the internal database, run:
customToolChainDef = target.get('Toolchain', '32-bit Visual Studio Toolchain'); target.remove(customToolChainDef);
See Also
target.create
| target.Toolchain
| target.MakefileBuilder
| target.BuildTool