使用 CMake 工具链编译从 MATLAB 代码生成的 C++ 源代码
CMake 是用于编译过程管理的第三方开源工具。在此示例中,当为一个简单的 MATLAB® 函数生成 C++ 源代码时,您可以指示代码生成器同时生成 CMakeLists.txt 文件。此文件不依赖于特定的编译工具,其中包含使用与平台无关的 CMake 语言编写的生成代码编译指令。
生成 C++ 源代码和 CMakeLists.txt 文件后,请调用 cmake 命令来执行以下操作:
使用
CMakeLists.txt文件生成标准编译文件。这些文件包括联编文件和 Ninja,以及 Microsoft® Visual Studio® 和 Xcode 工程编译。运行编译器和其他编译工具以创建一个可执行文件或库。
您也可以将 CMake 和相关联的 CMakeLists.txt 文件与命令行工具和 IDE(如 Microsoft Visual Studio、Microsoft Visual Studio Code、Xcode 和 CLion)结合使用。
除了能够生成不依赖于特定编译工具的 CMakeLists.txt 文件外,代码生成器还提供用于特定编译器和编译系统的 CMake 工具链定义。有关此替代工作流的详细信息,请参阅配置 CMake 编译过程。
定义 MATLAB 入口函数
定义简单的 MATLAB 入口函数 myfun,您打算为其生成并编译 C++ 代码。
type myfun.mfunction 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.cpp 和 main.h 示例文件。您将在下一步中复制并修改这些示例文件。
定义 C++ 主函数
将在上一步中生成的 main.cpp 和 main.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(¶meter);
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.h 和 main.cpp 文件包含在代码生成过程中,请分别设置 CustomInclude 和 CustomSource 属性。
由于您将在下一步中使用 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.