Register and use a Microsoft® Visual C/C++ (MSVC) toolchain running on a 64-bit Windows® platform to compile a 32-bit dynamic link library (DLL). This example uses a Microsoft® compiler. However, the concepts and programming interface apply for other toolchains. Once you register the toolchain, you can select it from a list of toolchains, and the code generator generates a makefile to build the code by using that toolchain. A toolchain consists of several tools, such as a compiler, linker, and archiver with multiple different configuration options. The toolchain compiles, links, and runs code on a specified platform. To access the files that this example uses, click Open Script.
This code checks that the platform is supported and that you have a supported version of Microsoft® Visual C/C++. The my_msvc_32bit_tc.m
toolchain definition can use the Microsoft® Visual Studio versions 9.0, 10.0, 11.0, 12.0, 14.0, or 15.0.
If you are not using a Windows® platform, or if you do not have a supported version of Microsoft® Visual C/C++, the example generates only code and a makefile, without running the generated makefile.
VersionNumbers = {'14.0'}; % Placeholder value if ~ispc supportedCompilerInstalled = false; else installed_compilers = mex.getCompilerConfigurations('C', 'Installed'); MSVC_InstalledVersions = regexp({installed_compilers.Name}, 'Microsoft Visual C\+\+ 20\d\d'); MSVC_InstalledVersions = cellfun(@(a)~isempty(a), MSVC_InstalledVersions); if ~any(MSVC_InstalledVersions) supportedCompilerInstalled = false; else VersionNumbers = {installed_compilers(MSVC_InstalledVersions).Version}'; supportedCompilerInstalled = true; end end
The example function for the dynamic link library, myMatlabFunction.m
, multiplies a number by two.
function y = myMatlabFunction(u) % myMatlabFunction: Returns twice its input. % Copyright 2017 The MathWorks, Inc. %#codegen assert(isa(u, 'double'), 'The input must be a "double".'); assert(all([1, 1] == size( u )), 'The input must be a scalar.'); y = double(u + u);
The my_msvc_32bit_tc.m
toolchain definition function takes in an argument containing the Visual Studio version number. In this example, the commands that create and configure this toolchain are:
tc = my_msvc_32bit_tc(VersionNumbers{end}); save my_msvc_32bit_tc tc;
Executing "H:\Examples\coder-ex19875030\my_msvc_32bit_tc"... Executed "H:\Examples\coder-ex19875030\my_msvc_32bit_tc".
Before the code generator can use a toolchain for the build process, the RTW.TargetRegistry
must contain the toolchain registration. This registration can come from any rtwTargetInfo.m
file on the MATLAB path. MATLAB will load a new registration if the RTW.TargetRegistry
is reset.
Create the rtwTargetInfo.m
file from the corresponding text file myRtwTargetInfo.txt
.
function myRtwTargetInfo(tr) %RTWTARGETINFO Registration file for custom toolchains. % Copyright 2012-2017 The MathWorks, Inc. tr.registerTargetInfo(@createToolchainRegistryFor32BitMSVCToolchain); end % ------------------------------------------------------------------------- % Create the ToolchainInfoRegistry entries % ------------------------------------------------------------------------- function config = createToolchainRegistryFor32BitMSVCToolchain config(1) = coder.make.ToolchainInfoRegistry; config(1).Name = 'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)'; config(1).FileName = fullfile(fileparts(mfilename('fullpath')), 'my_msvc_32bit_tc.mat'); config(1).TargetHWDeviceType = {'Intel->x86-32 (Windows32)','AMD->x86-32 (Windows32)','Generic->Unspecified (assume 32-bit Generic)'}; config(1).Platform = {'win64'}; end
copyfile myRtwTargetInfo.txt rtwTargetInfo.m RTW.TargetRegistry.getInstance('reset');
To generate the 32-bit dynamic link library (DLL), create a 'dll'
code generation configuration object. Specifying 'dll'
directs the linker (a build tool in the toolchain) to use "Shared Library" linker commands.
cfg = coder.config('dll');
To successfully generate code that is compatible with 32-bit hardware, the generated code must use the correct underlying C types (for example, int
, signed char
, and others). These types are the basis for typedef
statements for sized types (for example, uint8
, int16
, and others). Set the configuration with the command:
cfg.HardwareImplementation.ProdHWDeviceType = ... 'Generic->Unspecified (assume 32-bit Generic)';
Set the name of the Toolchain
property to match the Name
that you specify in the rtwTargetInfo.m
file.
cfg.Toolchain = ... 'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)';
To provide confirmation of compiler flags that the toolchain uses to build the DLL, select verbose status reporting.
cfg.Verbose = true;
When the Microsoft® compilers are not installed, the code generator generates only code and the makefile. When the supported compilers are installed, the code generator builds the 32-bit binary file.
if supportedCompilerInstalled cfg.GenCodeOnly = false; else cfg.GenCodeOnly = true; end
To use the toolchain for code generation and build the DLL (if build is enabled), at the command prompt, enter:
codegen -config cfg myMatlabFunction -args { double(1.0) };
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows) ### Creating 'H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_rtw.mk' ... ### Building 'myMatlabFunction': nmake -f myMatlabFunction_rtw.mk all H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction>set "VSCMD_START_DIR=H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction" H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\\VC\Auxiliary\Build\vcvarsall.bat" amd64_x86 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.0.26730.12 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64_x86' Microsoft (R) Program Maintenance Utility Version 14.11.25507.1 Copyright (C) Microsoft Corporation. All rights reserved. cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_initialize.c" myMatlabFunction_initialize.c cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_terminate.c" myMatlabFunction_terminate.c cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction.c" myMatlabFunction.c ### Creating dynamic library ".\myMatlabFunction.dll" ... link /MACHINE:X86 /DEBUG /DEBUGTYPE:cv /INCREMENTAL:NO /NOLOGO kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -dll -def:myMatlabFunction.def -out:.\myMatlabFunction.dll @myMatlabFunction_rtw.rsp Creating library .\myMatlabFunction.lib and object .\myMatlabFunction.exp ### Created: .\myMatlabFunction.dll ### Successfully generated all binary outputs.
If you have a supported version of the compiler installed, you can build the 32-bit executable by using a C main function. You can use the executable to test that the generated code works as expected.
cfge = coder.config('exe'); cfge.CustomInclude = pwd; cfge.CustomSource = 'myMatlabFunction_main.c'; cfge.GenCodeOnly = cfg.GenCodeOnly; cfge.Verbose = true; cfge.Toolchain = ... 'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)'; codegen -config cfge myMatlabFunction -args { double(1.0) }; if supportedCompilerInstalled pause(5); %wait for EXE to get generated system('myMatlabFunction 3.1416'); % Expected output: myMatlabFunction(3.1416) = 6.2832 end
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows) ### Creating 'H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_rtw.mk' ... ### Building 'myMatlabFunction': nmake -f myMatlabFunction_rtw.mk all H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction>set "VSCMD_START_DIR=H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction" H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\\VC\Auxiliary\Build\vcvarsall.bat" amd64_x86 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.0.26730.12 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64_x86' Microsoft (R) Program Maintenance Utility Version 14.11.25507.1 Copyright (C) Microsoft Corporation. All rights reserved. cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_initialize.c" myMatlabFunction_initialize.c cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_terminate.c" myMatlabFunction_terminate.c cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction.c" myMatlabFunction.c cl -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_main.obj" "H:\Examples\coder-ex19875030\myMatlabFunction_main.c" myMatlabFunction_main.c ### Creating standalone executable "H:\Examples\coder-ex19875030\myMatlabFunction.exe" ... link /MACHINE:X86 /DEBUG /DEBUGTYPE:cv /INCREMENTAL:NO /NOLOGO kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -out:H:\Examples\coder-ex19875030\myMatlabFunction.exe @myMatlabFunction_rtw.rsp ### Created: H:\Examples\coder-ex19875030\myMatlabFunction.exe ### Successfully generated all binary outputs. myMatlabFunction(3.1416) = 6.2832
To unregister the toolchain, enter:
delete ./rtwTargetInfo.m RTW.TargetRegistry.getInstance('reset');