Hauptinhalt

Add Custom Toolchains to MATLAB® Coder™ Build Process

A toolchain is a collection of tools required to compile and link code for a specified platform. The tools can include compilers, linkers, and archivers. You can configure the tools in a toolchain with multiple options, and group tool specifications into types of configurations.

This example shows how to create, register, and use a toolchain to build an executable file using the Intel® compiler for 64-bit Windows® with the Microsoft® compatible compiler driver. The Intel compiler uses syntax that is compatible with Microsoft Visual Studio tools, and it builds the executable for a 64-bit Windows target machine. However, the concepts and programming interface demonstrated in the example apply for all toolchains, including those that cross-compile for target hardware.

Prerequisites and Limitations:

  • This example can only be run on a Windows machine.

  • To run the example, you need to have Microsoft Visual Studio installed.

  • To run the example, you need to have Intel OneAPI installed in its default location.

About the codertime Function

In this example, you generate C code from the codertime MATLAB® function. This function uses the MATLAB function datetime to return one component of the current time, as an integer, depending on the value of the input argument:

  • When the input argument is 1, the function returns the current hour.

  • When the input argument is 2, the function returns the current minute.

  • Otherwise, the function returns the current second.

The function source file, codertime.m, and the example main file, codertime_main.c, are provided here. Use the type function to see their content.

type("codertime.m")
function timeComponent = codertime(componentID) %# Codegen
  arguments (Input)
    componentID (1,1) uint8;
  end
  arguments (Output)
    timeComponent (1,1) uint8;
  end

%CODERTIME - Return one of the current time components: hour, minute, or
% second. This function is part of the example Add Custom Toolchains to
% MATLAB Coder Build Process.
%
% timeComponent = codertime(componentID) uses the function datetime to 
%                 return one of the components of the current time.
%
% componentID is a one-byte unsigned integer that specifies which time
% component the function returns:
%   * When componentID is 1, the function returns the current hour.
%   * When componentID is 2, the function returns the current minute.
%   * Otherwise, the function returns the current second.
% The return value, timeComponent, is a one-byte unsigned integer.

% Copyright 2026 The MathWorks, Inc. 

  if(componentID == 1)
    timeComponent = datetime().Hour;
  elseif(componentID == 2)
    timeComponent = datetime().Minute;
  else
    timeComponent = datetime().Second;
  end
end
type("codertime_main.c")
/** codertime_main.c
 * Example main for the example:
 * Add Custom Toolchains to MATLAB Coder Build Process.
 *
 * Copyright 2026 The MathWorks, Inc.
 **/
#include <stdio.h>
#include "codertime.h"
#include "codertime_initialize.h"
#include "codertime_terminate.h"

int main()
{
    codertime_initialize();

    printf("The current 24-hour time is %0.2u:%0.2u:%0.2u\n",
           codertime(1),codertime(2),codertime(3));

    codertime_terminate();

    return 0;
}

Create Toolchain Object

Create a target.Toolchain object with definitions suitable for an Intel compiler on a 64-bit Windows platform, and add it to the internal database so that it can be used by the code generator.

Retrieve from the internal database all the target.Processor objects compatible with Intel compiler on a 64-bit Windows platform. Store the retrieved array in the variable processorObjs.

processorObjs = [target.get("Processor",Name="x86-64 (Windows64)"), ...
  target.get("Processor","Custom Processor-MATLAB Host Computer")];

Create a skeleton toolchain object using the necessary name-value arguments.

toolChainObj = target.create("Toolchain", ...
  Name="Intel OneAPI - using Microsoft Compatible Compiler Driver", ...
  MakeToolType="NMake", ...
  MakeTool="nmake", ...  
  HardwareSupport=processorObjs, ... % Previously created object array.
  CCompiler="icx", ...
  CppCompiler="icx -EHs", ...
  Linker="link", ...
  CppLinker="link", ...
  CompilerFlags="-nologo", ...
  LinkerFlags="-nologo", ...
  Archiver="lib -nologo", ...
  ObjectExtension=".obj", ...
  ExecutableExtension=".exe", ...
  SharedLibraryExtension=".dll", ...
  StaticLibraryExtension=".lib", ...
  CommandFile="@");

Use the CCompiler, CppCompiler, Linker, and CppLinker arguments to specify C and C++ compilers and linkers in the toolchain. In the value for CppCompiler, note the flag -EHs, which is only used by the C++ the compiler. The specified CompilerFlags and LinkerFlags are common flags, used for both C and C++ compilers and linkers.

For the HardwareSupport argument, use the target.Processor object array, previously retrieved from the internal database.

These arguments specify extensions for derived files generated by the toolchain tools:

  • ObjectExtension=".obj"

  • ExecutableExtension=".exe"

  • SharedLibraryExtension=".dll"

  • StaticLibraryExtension=".lib"

Compilers, linkers, and archivers can read multiple command-line flags from a text file, instead of directly from the command line, helping the build process avoid exceeding the command-line maximum length limitation. Enable this feature with the CommandFile argument. The build process prefixes the text file name with @.

Set preprocessor definitions to be used, by default, when building code with this toolchain. Specifically, in the example, specify the definition that disables some compiler warnings about using ANSI C functions for which newer alternatives are available.

toolChainObj.BuildRequirements.Defines = "-D_CRT_SECURE_NO_WARNINGS";

Create a target.Command object to specify a batch file to use for setting up the environment for the toolchain.

When the full path of the batch file contains no white spaces, you can use this format to create the object:

target.create("Command","fullPath")

Here, fullPath is the full path of the batch file. When the full path contains white spaces, use the String property to prevent the spaces from being interpreted as separators between the command and arguments. For the example, use this:

setupCMD = target.create("Command", ...
    String="C:\Program Files (x86)\Intel\oneAPI\setvars.bat");

Alternatively, you can use the value of the environment variable ONEAPI_ROOT, if it is defined, to create your setup command:

if(isenv("ONEAPI_ROOT"))
  setupCMD = target.create("Command",String="$(ONEAPI_ROOT)\setvars.bat");
end

Use the setup command with your toolchain.

toolChainObj.EnvironmentConfiguration.SetupCommand = setupCMD;

Each directive specifies the command line flag to use with the tool (compiler or linker) for controlling a specific behavior of the tool. For example, the value of the Debug directive specifies the command line flag that enables debug symbol generation when passed to the compiler. Specifically, compilers in this toolchain enable debug symbol generation when the flag "-Zi" is passed in the command line. So you specify the Debug directive as "-Zi".

Iterate over the compilers in the toolchain, and for each specify the required directives.

tcCompilers = [toolChainObj.getBuildToolOfType("C Compiler"), ...
  toolChainObj.getBuildToolOfType("C++ Compiler")];

for curCompiler = tcCompilers
  curCompiler.setDirective(CompileFlag="-c")
  curCompiler.setDirective(Debug="-Zi")
  curCompiler.setDirective(DisableOptimization="/Od")
  curCompiler.setDirective(EnableOptimization="/O2")
  curCompiler.setDirective(IncludeSearchPath="-I")
  curCompiler.setDirective(OutputFlag="-Fo")
  curCompiler.setDirective(PreprocessFile="-E")
  curCompiler.setDirective(PreprocessorDefine="-D")
end

Iterate over the linkers in the toolchain, and for each specify the required directives.

tcLinkers = [toolChainObj.getBuildToolOfType("Linker"), ...
  toolChainObj.getBuildToolOfType("C++ Linker")];

for curLinker = tcLinkers
  curLinker.setDirective(Library="")
  curLinker.setDirective(LibrarySearchPath="-L")
  curLinker.setDirective(OutputFlag="-out:")
  curLinker.setDirective(Debug="")
  curLinker.setDirective(Shared="-dll")
  curLinker.setDirective(DefFile="-def:")
end

The last directive in the loop, DefFile, is necessary when you configure the MATLAB® Coder™ to build a shared library from your MATLAB source code instead of an executable file. In this case, the directive DefFile is used to include a module definition file with information about the exported variable and function symbols.

Specify the OutputFlag directive to indicate the prefix of the static library to be created by the archiver of the toolchain.

tcArchiver = toolChainObj.getBuildToolOfType("Archiver");
tcArchiver.setDirective(OutputFlag="-out:")

Add Toolchain Object to Internal Database

Use the target.add function to add the toolchain and associated objects to the internal database. Store the added in the variable addedObjects so that you can remove them later from the database.

addedObjects = target.add(toolChainObj,SuppressOutput=true);

Use Toolchain Object

To use the newly created toolchain object, create a coder.config object configured to create an executable using the toolchain.

coderConfigObj = coder.config("exe");
coderConfigObj.Toolchain = "Intel OneAPI - using Microsoft Compatible Compiler Driver";

To have the code generator build a shared library, specify the output type as "DLL":

coderConfigObj.OutputType = "DLL";

To have the code generator build a static library, specify the output type as "LIB":

coderConfigObj.OutputType = "LIB";

Configure the coder configuration object to use the provided example main function. This is unnecessary when you specify the output type as a shared or static library, but it is required for generating an executable.

coderConfigObj.CustomSource = "codertime_main.c";

If you do not have the Intel compilers installed, configure the config object to only generate the code and makefile, without generating the executable:

coderConfigObj.GenCodeOnly = true;

Use the codegen command to generate the code and makefile that uses the new toolchain.

codegen -config coderConfigObj codertime
Code generation successful.

If you built the executable, use the system function in the Command Window to run it:

system("codertime");

Remove Added Objects from Database

To remove the objects you added to the internal database, use the target.remove function.

target.remove(addedObjects,SuppressOutput=true)

See Also

| | | | | | |