主要内容

使用 CMake 工具链编译从 MATLAB 代码生成的 C++ 源代码

CMake 是用于编译过程管理的第三方开源工具。在此示例中,当为一个简单的 MATLAB® 函数生成 C++ 源代码时,您可以指示代码生成器同时生成 CMakeLists.txt 文件。此文件不依赖于特定的编译工具,其中包含使用与平台无关的 CMake 语言编写的生成代码编译指令。

生成 C++ 源代码和 CMakeLists.txt 文件后,请调用 cmake 命令来执行以下操作:

  1. 使用 CMakeLists.txt 文件生成标准编译文件。这些文件包括联编文件和 Ninja,以及 Microsoft® Visual Studio® 和 Xcode 工程编译。

  2. 运行编译器和其他编译工具以创建一个可执行文件或库。

您也可以将 CMake 和相关联的 CMakeLists.txt 文件与命令行工具和 IDE(如 Microsoft Visual Studio、Microsoft Visual Studio Code、Xcode 和 CLion)结合使用。

除了能够生成不依赖于特定编译工具的 CMakeLists.txt 文件外,代码生成器还提供用于特定编译器和编译系统的 CMake 工具链定义。有关此替代工作流的详细信息,请参阅配置 CMake 编译过程

定义 MATLAB 入口函数

定义简单的 MATLAB 入口函数 myfun,您打算为其生成并编译 C++ 代码。

type myfun.m
function a = myfun(a) %#codegen
a = a + sqrt(a);
end

生成 C++ 源代码

仅生成 C++ 源代码。将输入的类型指定为双精度标量。将代码生成文件夹的名称指定为 myfun_trial_codegen

codegen -config:lib -lang:c++ -c myfun -args 0 -d myfun_trial_codegen
Code generation successful.

鉴于您在 MATLAB 代码中将同一变量同时用作输入和输出,生成的 C++ 入口函数使用指针传递和返回此变量。因此,该函数具有以下签名:

void myfun(double *a)

除了入口函数代码外,代码生成器还会在 myfun_trial_codegen/examples 文件夹中生成 main.cppmain.h 示例文件。您将在下一步中复制并修改这些示例文件。

定义 C++ 主函数

将在上一步中生成的 main.cppmain.h 示例文件复制到当前工作文件夹。修改 main 函数,使其接受双精度标量输入,调用生成的 C++ 入口函数 myfun,并打印 myfun 的输出。

type main.cpp
#include "main.h"
#include "myfun.h"
#include "myfun_terminate.h"

int main(int argc, char* argv[])
{
  if (argc < 2) {
    std::cout << "Usage: " << argv[0] << " number" << std::endl;
    return 1;
  }

  double inputValue = atof(argv[1]);
  double parameter = inputValue;
  myfun(&parameter);
  double outputValue = parameter;
    
  std::cout << "Adding the number " << inputValue << " to its own square root produces " << outputValue
            << std::endl;

  myfun_terminate();
  return 0;
}

生成 C++ 源代码和 CMakeLists.txt 文件以编译可执行文件

定义代码生成配置对象 cfg 以编译 C++ 可执行文件。要将 main.hmain.cpp 文件包含在代码生成过程中,请分别设置 CustomIncludeCustomSource 属性。

由于您将在下一步中使用 CMake 编译生成的代码,请配置该代码生成器以进行以下生成:

  • 通过将 GenCodeOnly 属性设置为 true 来仅生成源代码。

  • 通过将 Toolchain 属性设置为 "CMake" 来生成 CMakeLists.txt 文件。

cfg = coder.config("exe");
cfg.TargetLang = "C++";

cfg.CustomSource = "main.cpp";
cfg.CustomInclude = {pwd};

cfg.GenCodeOnly = true;
cfg.Toolchain = "CMake";

通过运行 codegen 命令生成源代码和 CMakeLists.txt 文件。将代码生成文件夹的名称指定为 myfun_codegen

codegen -config cfg myfun -args 0 -d myfun_codegen
Code generation successful.

方法 1:切换到您选择的 IDE

CMake 和相关联的 CMakeLists.txt 文件广泛用于编译 C++ 代码,您可以直接将它们与命令行工具和 IDE(如 Microsoft Visual Studio、Microsoft Visual Studio Code、Xcode 和 CLion)结合使用。因此,在工作流的这一环节,您可以在所选的 IDE 中打开代码生成文件夹 myfun_codegen,并继续配置、编译和调试您的 C++ 工程。

例如,如果您使用 Visual Studio Code,请运行以下命令:

system("code ./myfun_codegen");
'code' is not recognized as an internal or external command, 
operable program or batch file. 

方法 2:在 MATLAB 命令行中调用 cmake 以编译可执行文件

创建一个编译文件夹 myfun_build(如果尚不存在)。导航到该文件夹。

if (~exist("myfun_build","dir"))
    mkdir myfun_build
end
cd myfun_build

调用 cmake 命令以编译适用于您系统上可用的工具链的工程。在此示例中,cmake 编译一个适用于 Visual Studio 2019 工具链的工程。因此,它在 myfun_build 文件夹中创建一个 myfun.vcxproj 文件及其他支持文件。

system("cmake ../myfun_codegen");
'cmake' is not recognized as an internal or external command, 
operable program or batch file. 

再次调用 cmake 命令以编译此工程,并在您的主工作文件夹中创建一个可执行文件 myfun

system("cmake --build .");
'cmake' is not recognized as an internal or external command, 
operable program or batch file. 

运行生成的可执行文件

使用示例输入运行生成的可执行文件 myfun

cd ..;
if isunix
    system('./myfun 144');
elseif ispc
    system('myfun 144');
else
    disp('Platform is not supported')
end
'myfun' is not recognized as an internal or external command, 
operable program or batch file. 

另请参阅

主题