Main Content

Generate C Code at the Command Line

In this tutorial, you use the MATLAB® Coder™ codegen command to generate a static C library for a MATLAB function. You first generate C code that can accept only inputs that have fixed preassigned size. You then generate C code that can accept inputs of many different sizes.

You can also generate code by using the MATLAB Coder app. For a tutorial on this workflow, see Generate C Code by Using the MATLAB Coder App.

Tutorial Files: Euclidean Distance

Open this example to obtain the files for this tutorial.

Description of Tutorial Files

This tutorial uses the euclidean_data.mat, euclidean.m, euclidean_test.m, build_lib_fixed.m, and build_lib_variable.m files.

  • The MATLAB data file euclidean_data.mat contains two pieces of data: a single point in three-dimensional Euclidean space and a set of several other points in three-dimensional Euclidean space. More specifically:

    • x is a 3-by-1 column vector that represents a point in three-dimensional Euclidean space.

    • cb is a 3-by-216 array. Each column in cb represents a point in three-dimensional Euclidean space.

  • The MATLAB file euclidean.m contains the function euclidean that implements the core algorithm in this example. The function takes x and cb as inputs. It calculates the Euclidean distance between x and each point in cb and returns these quantities:

    • The column vector y_min, which is equal to the column in cb that represents the point that is closest to x.

    • The column vector y_max, which is equal to the column in cb that represents the point that is farthest from x.

    • The 2-dimensional vector idx that contains the column indices of the vectors y_min and y_max in cb.

    • The 2-dimensional vector distance that contains the calculated smallest and largest distances to x.

    function [y_min,y_max,idx,distance] = euclidean(x,cb)
    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx(1)=1;
    idx(2)=1;
    
    distance(1)=norm(x-cb(:,1));
    distance(2)=norm(x-cb(:,1));
    
    % Find the vector in cb with minimum distance to x
    % Find the vector in cb with maximum distance to x
    for index=2:size(cb,2)
        d=norm(x-cb(:,index));
        if d < distance(1)
            distance(1)=d;
            idx(1)=index;
        end
        if d > distance(2)
            distance(2)=d;
            idx(2)=index;
        end
    end
    
    % Output the minimum and maximum distance vectors
    y_min=cb(:,idx(1));
    y_max=cb(:,idx(2));
    
    end
  • The MATLAB script euclidean_test.m loads the data file euclidean_data.mat into the workspace. It then calls the function euclidean to calculate y_min, y_max, idx, and distance. The script then displays the calculated quantities at the command line.

    Loading euclidean_data.mat is the preprocessing step that is executed before calling the core algorithm. Displaying the results is the post-processing step.

    % Load test data 
    load euclidean_data.mat
    
    % Determine closest and farthest points and corresponding distances
    [y_min,y_max,idx,distance] = euclidean(x,cb);
    
    % Display output for the closest point
    disp('Coordinates of the closest point are: ');
    disp(num2str(y_min'));
    disp(['Index of the closest point is ', num2str(idx(1))]);
    disp(['Distance to the closest point is ', num2str(distance(1))]);
    
    disp(newline);
    
    % Display output for the farthest point
    disp('Coordinates of the farthest point are: ');
    disp(num2str(y_max'));
    disp(['Index of the farthest point is ', num2str(idx(2))]);
    disp(['Distance to the farthest point is ', num2str(distance(2))]);
  • The build scripts build_lib_fixed.m and build_lib_variable.m contain commands for generating static C libraries from your MATLAB code that accept fixed-size and variable-size inputs, respectively. The contents of these scripts are shown later in the tutorial, when you generate the C code.

Tip

You can generate code from MATLAB functions by using MATLAB Coder. Code generation from MATLAB scripts is not supported.

Use test scripts to separate the pre- and post-processing steps from the function implementing the core algorithm. This practice enables you to easily reuse your algorithm. You generate code for the MATLAB function that implements the core algorithm. You do not generate code for the test script.

Generate C Code for the MATLAB Function

Run the Original MATLAB Code

Run the test script euclidean_test.m in MATLAB. The output displays y, idx, and distance.

Coordinates of the closest point are: 
0.8         0.8         0.4
Index of the closest point is 171
Distance to the closest point is 0.080374


Coordinates of the farthest point are: 
0  0  1
Index of the farthest point is 6
Distance to the farthest point is 1.2923

Make the MATLAB Code Suitable for Code Generation

To make your MATLAB code suitable for code generation, you use the Code Analyzer and the Code Generation Readiness Tool. The Code Analyzer in the MATLAB Editor continuously checks your code as you enter it. It reports issues and recommends modifications to maximize performance and maintainability. The Code Generation Readiness Tool screens the MATLAB code for features and functions that are not supported for code generation.

Certain MATLAB built-in functions and toolbox functions, classes, and System objects that are supported for C/C++ code generation have specific code generation limitations. These limitations and related usage notes are listed in the Extended Capabilities sections of their corresponding reference pages. For more information, see Functions and Objects Supported for C/C++ Code Generation.

  1. Open euclidean.m in the MATLAB Editor. The Code Analyzer message indicator in the top right corner of the MATLAB Editor is green. The analyzer did not detect errors, warnings, or opportunities for improvement in the code.

  2. After the function declaration, add the %#codegen directive:

    function [y,idx,distance] = euclidean(x,cb) %#codegen
    The %#codegen directive prompts the Code Analyzer to identify warnings and errors specific to code generation.

    The Code Analyzer message indicator becomes red, indicating that it has detected code generation issues.

    Code Analyzer window containing sample code, showing red indicator and underlining corresponding to detected code generation issues

  3. To view the warning messages, move your cursor to the underlined code fragments. The warnings indicate that code generation requires the variables idx and distance to be fully defined before subscripting them. These warnings appear because the code generator must determine the sizes of these variables at their first appearance in the code. To fix this issue, use the ones function to simultaneously allocate and initialize these arrays.

    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx = ones(1,2);
    
    distance = ones(1,2)*norm(x-cb(:,1));

    The Code Analyzer message indicator becomes green again, indicating that it does not detect any more code generation issues.

    Code Analyzer window containing sample code, showing green indicator

    For more information about using the Code Analyzer, see Check Code for Errors and Warnings Using the Code Analyzer.

  4. Save the file.

  5. To run the Code Generation Readiness Tool, call the coder.screener function from the MATLAB command line.

    coder.screener('euclidean')

    The tool does not detect any code generation issues for euclidean. For more information, see Code Generation Readiness Tool.

    Note

    The Code Analyzer and the Code Generation Readiness Tool might not detect all code generation issues. After eliminating the errors or warnings that these tools detect, generate code by using MATLAB Coder to determine if your MATLAB code has other compliance issues.

You are now ready to compile your code by using the MATLAB Coder app. Here, compilation refers to the generation of C/C++ code from your MATLAB code.

Note

Compilation of MATLAB code refers to the generation of C/C++ code from the MATLAB code. In other contexts, the term compilation could refer to the action of a C/C++ compiler.

Defining Input Types

Because C uses static typing, the code generator must determine the class, size, and complexity of all variables in the MATLAB files at code generation time, also known as compile time. Therefore, when you generate code for the files, you must specify the properties of all input arguments to the entry-point functions. An entry-point function is a top-level MATLAB function from which you generate code.

When you generate code by using the codegen command, use the -args option to specify sample input parameters to the entry-point functions. The code generator uses this information to determine the properties of the input arguments.

In the next step, you use the codegen command to generate a MEX file from your entry-point function euclidean.

Check for Run-Time Issues

You generate a MEX function from your entry-point function. A MEX function is generated code that can be called from inside MATLAB. You run the MEX function and check whether the generated MEX function and the original MATLAB function have the same functionality.

It is a best practice to perform this step because you can detect and fix run-time errors that are harder to diagnose in the generated C code. By default, the MEX function includes memory integrity checks. These checks perform array bounds and dimension checking. The checks detect violations of memory integrity in code generated for MATLAB functions. For more information, see Control Run-Time Checks.

To convert MATLAB code to efficient C/C++ source code, the code generator introduces optimizations that, in certain situations, cause the generated code to behave differently than the original source code. See Differences Between Generated Code and MATLAB Code.

  1. Generate a MEX file for euclidean.m by using the codegen command. To verify the MEX function, run the test script euclidean_test with calls to the MATLAB function euclidean replaced with calls to the generated MEX function.

    % Load the test data
    load euclidean_data.mat
    % Generate code for euclidean.m with codegen. Use the test data as example input.
    codegen euclidean.m -args {x,cb} -test euclidean_test

    • By default, codegen generates a MEX function named euclidean_mex in the current folder.

    • You use the -args option to specify sample input parameters to the entry-point function euclidean. The code generator uses this information to determine the properties of the input arguments.

    • You use the -test option to run the test file euclidean_test.m. This option replaces the calls to euclidean in the test file with calls to euclidean_mex.

    The output is:

    Running test file: 'euclidean_test' with MEX function 'euclidean_mex'.
    Coordinates of the closest point are: 
    0.8         0.8         0.4
    Index of the closest point is 171
    Distance to the closest point is 0.080374
    
    
    Coordinates of the farthest point are: 
    0  0  1
    Index of the farthest point is 6
    Distance to the farthest point is 1.2923
    This output matches the output that was generated by the original MATLAB function and verifies the MEX function. Now you are ready to generate standalone C code for euclidean.

Note

Before generating standalone C/C++ code from your MATLAB code, generate a MEX function. Run the generated MEX function and make sure it has the same run-time behavior as your MATLAB function. If the generated MEX function produces answers that are different from MATLAB, or produces an error, you must fix these issues before proceeding to standalone code generation. Otherwise, the standalone code that you generate might be unreliable and have undefined behavior.

Generate C Code

The build script build_lib_fixed.m contains the commands that you use to generate code for euclidean.m.

% Load the test data
load euclidean_data.mat
% Generate code for euclidean.m with codegen. Use the test data as example input.
codegen -report -config:lib euclidean.m -args {x, cb}
Note that:

  • codegen reads the file euclidean.m and translates the MATLAB code into C code.

  • The -report option instructs codegen to generate a code generation report that you can use to debug code generation issues and verify that your MATLAB code is suitable for code generation.

  • The -config:lib option instructs codegen to generate a static C library instead of generating the default MEX function.

  • The -args option instructs codegen to generate code for euclidean.m using the class, size, and complexity of the sample input parameters x and cb.

Instead of generating a C static library, you can choose to generate a MEX function or other C/C++ build types by using suitable options with the codegen command. For more information on the various code generation options, see codegen.

  1. Run the build script.

    MATLAB processes the build file and outputs the message:

    Code generation successful: View report.
    The code generator produces a standalone C static library euclidean in work\codegen\lib\euclidean. Here, work is the folder that contains your tutorial files.

  2. To view the code generation report in the Report Viewer, click View report.

    If the code generator detects errors or warnings during code generation, the report describes the issues and provides links to the problematic MATLAB code. See Code Generation Reports.

Tip

Use a build script to generate code at the command line. A build script automates a series of MATLAB commands that you perform repeatedly at the command line, saving you time and eliminating input errors.

Compare the Generated C Code to Original MATLAB Code

To compare your generated C code to the original MATLAB code, open the C file, euclidean.c, and the euclidean.m file in the MATLAB Editor.

Important information about the generated C code:

  • The function signature is:

    void euclidean(const double x[3], const double cb[648], double y_min[3], double
                   y_max[3], double idx[2], double distance[2])

    const double x[3] corresponds to the input x in your MATLAB code. The size of x is 3, which corresponds to the total size (3 x 1) of the example input you used when you generated code for your MATLAB code.

    const double cb[648] corresponds to the input cb in your MATLAB code. The size of cb is 648, which corresponds to the total size (3 x 216) of the example input you used when you generated code for your MATLAB code. In this case, the generated code uses a one-dimensional array to represent a two-dimensional array in the MATLAB code.

    The generated code has four additional input arguments: the arrays y_min, y_max, idx, and distance. These arrays are used to return the output values. They correspond to the output arguments y_min, y_max, idx, and distance in the original MATLAB code.

  • The code generator preserves your function name and comments. When possible, the code generator preserves your variable names.

    Note

    If a variable in your MATLAB code is set to a constant value, it does not appear as a variable in the generated C code. Instead, the generated C code contains the actual value of the variable.

With Embedded Coder®, you can interactively trace between MATLAB code and generated C/C++ code. See Interactively Trace Between MATLAB Code and Generated C/C++ Code (Embedded Coder).

Generate C Code for Variable-Size Inputs

The C function that you generated for euclidean.m can accept only inputs that have the same size as the sample inputs that you specified during code generation. However, the input arrays to the corresponding MATLAB function can be of any size. In this part of the tutorial, you generate C code from euclidean.m that accepts variable-size inputs.

Suppose that you want the dimensions of x and cb in the generated C code to have these properties:

  • The first dimension of both x and cb can vary in size up to 3.

  • The second dimension of x is fixed and has the value 1.

  • The second dimension of cb can vary in size up to 216.

To specify these input properties, use the coder.typeof function. coder.typeof(A,B,1) specifies a variable-size input with the same class and complexity as A and upper bounds given by the corresponding element of the size vector B. Use the build script build_lib_variable.m that uses coder.typeof to specify the properties of variable-size inputs in the generated C library.

% Load the test data
load euclidean_data.mat

% Use coder.typeof to specify variable-size inputs
eg_x=coder.typeof(x,[3 1],1);
eg_cb=coder.typeof(cb,[3 216],1);

% Generate code for euclidean.m using coder.typeof to specify
% upper bounds for the example inputs
codegen -report -config:lib euclidean.m -args {eg_x,eg_cb}

You can now generate code by following the same steps as before. The function signature for the generated C code in euclidean.c now reads:

void euclidean(const double x_data[], const int x_size[1], const double cb_data[],
               const int cb_size[2], double y_min_data[], int y_min_size[1],
               double y_max_data[], int y_max_size[1], double idx[2], double
               distance[2])
The arguments x_data, cb_data, y_min_data, and y_max_data correspond to the input arguments x and cb and the output arguments y_min and y_max in the original MATLAB function. The C function now accepts four additional input arguments x_size, cb_size, y_min_size and y_max_size that specify the sizes of x_data, cb_data, y_min_data, and y_max_data at run time.

Next Steps

GoalMore Information

Learn about code generation support for MATLAB built-in functions and toolbox functions, classes, and System objects

Functions and Objects Supported for C/C++ Code Generation

Generate C++ code

C++ Code Generation

Create and edit input types interactively

Create and Edit Input Types by Using the Coder Type Editor

Generate and modify an example C main function and use it to build a C executable program

Use an Example C Main in an Application

Package generated files into a compressed file

Package Code for Other Development Environments

Optimize the execution speed or memory usage of generated code

Optimize Generated C/C++ and MEX Code

Integrate your custom C/C++ code into the generated code

Call Custom C/C++ Code from the Generated Code

Learn about the code generation report

Code Generation Reports

Interactively Trace Between MATLAB Code and Generated C/C++ Code (Embedded Coder)

See Also

|