cmake基础示例:如何编译【跨平台】的动态库和应用程序-600学习网
600学习网终身会员188,所有资源无秘无压缩-购买会员
目录
·示例代码
我的图书馆
我的应用程序
·Linux下的构建过程
Cmake配置
进行编译
编译并执行
·Windows下的生成过程
cmake共形
建筑
调试
别人的经验是我们的阶梯!
你好,我是道哥。今天我将向您解释的技术知识是:[使用cmake构建跨平台动态库和应用程序]。
很久以前,我在Station B上传了几个小视频,介绍了如何在Windows和Linux平台上通过cmake和make这两个构建工具编译和链接动态库.静态库和可执行程序。
视频中的示例代码是预先编写的,因此重点是构建链接。它主要介绍了动态库之间以及应用程序和动态库之间的引用。
熟悉动态库和静态库的人应该能够轻松理解它们的内容。但不熟悉C语言的朋友似乎仍然有一点障碍。
本文主要简化视频中的示例代码,只使用一个动态库和一个可执行文件,并使用cmake构建工具演示Windows和Linux平台上的构建过程。
这篇文章的内容很基本。使用cmake构建跨平台程序可以视为入门教程!
示例代码
首先,查看测试代码的全貌:
Mylib:只有一个源文件,编译并输出一个动态库;
Myapp:只有一个源文件,它链接到mylib动态库,编译并输出可执行程序;
我的图书馆
在mylib目录中,有三个文件:mylib。h. mylib。c. 和CMakeLists.txt。内容如下:
上述代码主要用于Windows系统的动态导出库,但在Linux系统中不是必需的。
补充:在Windows系统中,xxx。dll和xxx。lib将在编译动态库时生成。xxx。dll是真正的库文件指令,xxx。lib只是一个符号表。
具体来说,在Windows中,编译动态库时,打开(定义)宏MYLIB_EXPORT,以下宏将生效:
#定义MYLIB_API_解密规范(dllexport)
这样,可以将两个函数my_add和my_sub的符号导出到mylib。lib文件。
当应用程序(myapp)和myapp使用动态库时。c包括mylib。h. 关闭宏MYLIB_EXPORT,以下宏将生效:
#定义MYLIB_API_解密规范(dllimport)
为了简化宏定义的复杂姓,这里不考虑静态库。
读取头文件后,让我们看看源文件mylib。抄送:
最后,让我们看看mylib/CMakeLists。txt文件:
关于cmake的语法,我不会说太多。我在这里只使用其中的几个。
注意一点:ADD_DEFINITIONS(-DMYLIB_EXPORT)。因为这个CMakeLists。txt用于编译动态库,在Windows平台上,必须在每个导出符号之前添加__declspec(dllexport),因此需要打开宏定义:MYLIB_export。
我的应用程序
应用程序的代码更简单。只有两个文件:myapp。c和CMakeLists.txt。内容如下:
HelloWorld级代码,无需解释!CMakeLists。txt如下:
最后一行TARGET_LINK_LIBRARIES(${PROJECT_NAME}mylib)表示应该链接动态库mylib。
在哪个目录中可以找到相应的头文件和库文件?
使用这两行指定查找目录:
这两个目录还不存在。我们将在编译时手动创建它们。
编译时,mylib的输出文件可以自动复制到指定目录。然而,为了不使问题复杂化,一些操作步骤是手动完成的,因此链接过程可以
为了避免污染源文件目录,请在最外面的目录中创建一个新的构建目录,然后执行cmake命令:
此时,在构建目录中,将生成以下文件:
CMakeCache.txt CMakeFiles cmake _ install.cmake Makefile myapp mylib
进行编译
我们可以分别输入mylib和myapp目录,执行make命令单独编译,或者直接编译构建目录中的所有目标。
现在直接编译build目录中的所有目标:
$cd~/tmp/cmake演示/构建
美元制造
扫描目标mylib的依赖项
〔25%〕构建C对象mylib/CMakeFiles/mylib.dir/mylib.co
〔50%〕链接C共享库libmylib.so
〔50%〕构建目标mylib
扫描目标myapp的依赖项
〔75%〕构建C对象myapp/CMakeFiles/myapp.dir/myapp.co
~/tmp/cmake_demo/myapp/myapp。c: 4:19:致命错误:mylib。h: 没有这样的文件或目录
#包括”mylib.h”^
编译已终止。
myapp/CMakeFiles/myapp.dir/build.make:62:目标”myapp/CMakeFile/myapp.dir/myapp.c.o”的配方失败
make〔2〕:***〔myapp/CMakeFiles/myapp.dir/myapp.co〕错误1
CMakeFiles/Makefile2:140:目标”myapp/CMakeFile/myapp.dir/all”的配方失败
make〔1〕:***〔myapp/CMakeFiles/myapp.dir/all〕错误2
Makefile:83:目标”all”的配方失败
make:**〔all〕错误2
从提示符中可以看到./mylib/libmylib。因此,文件已编译,但在编译可执行文件myapp:mylib时遇到错误。找不到h文件!
当我刚刚介绍myapp/CMakeLists时。txt文件,我说应用程序查找头文件的目录是myapp/include,而查找库文件的目录则是myapp/lib。
但这两个目录以及相应的头文件和库文件不存在!
因此,我们需要手动创建它并复制头文件mylib。h和库文件libmylib.so。操作流程如下:
美元cd~/tmp/cmake演示/myapp/
美元mkdir包括lib
$cp~/tmp/cmake演示/mylib/mylib.h./include/
$cp~/tmp/cmake/demo/build/mylib/libmylib.so./lib/
注意:库文件libmylib。所以刚刚编译的代码在build目录中。
准备头文件和库文件后,再次编译:
$cd~/tmp/cmake演示/构建/
美元制造
〔50%〕构建目标mylib
〔75%〕构建C对象myapp/CMakeFiles/myapp.dir/myapp.co
[100%]链接C可执行文件myapp
[100%]构建目标myapp
此时,可执行文件myapp将在build/myapp目录中生成。
测试.执行
$cd~/tmp/cmake演示/构建/myapp
美元/我的应用程序
ret1=7
ret2=3
完美的
由于我们在构建目录中进行编译,所以编译过程中的所有输出和中间文件都放在构建目录下,而不会污染源文件。
Windows下的生成过程
删除Linux系统中的构建文件夹,压缩测试代码,并将其复制到Windows系统以继续测试。
在Windows下编译时,很少使用命令行,并且大多数命令行是使用VS或VSCode编译的。
打开VSCode,然后打开测试代码文件夹cmake_demo:
因为需要使用cmake工具进行构建,所以需要在VSCode中安装cmake插件。(将不详细描述如何安装VSCode插件。)
步骤1:cmake配置
按键盘上的ctrl+shift+p,然后在命令窗口中选择Cmake:Configure。如果未看到此选项,请手动输入前面的字符,然后可以智能地将它们匹配到:
首次配置时,将弹出以下选项以选择编译器:
这里我们选择64位amd64。
配置的结果将在底部窗口的输出标签中输出,如下所示:
这表示cmake配置成功,CMakeLists。每个文件夹下的txt文件已正确执行。
现在,让我们看看资源管理器中的更改:构建目录是自动生成的,文件如下所示:
除了VSCode主动帮助我们之外,这个过程似乎与Linux系统中的相同。
第2步:编译
配置之后,下一步是编译。
按shift+F7,或单击VSCode底部的Build图标:
弹出编译目标列表:
在此处选择ALL_BUILD,即编译所有目标:mylib和myapp。输出如下:
查看编译后的输出文件:
我的图书馆。dll是编译的动态链接库,而mylib。lib是导入符号。
我的应用程序。exe是已编译的可执行程序。
第3步:执行
让我们执行myapp。exe在命令行窗口中执行:
提示错误:找不到动态链接库!
手动复制mylib。dll到myuapp的同一目录。exe,然后执行myapp。exe再次执行:
完美的
但是,由于您已经使用VSCode进行了编译,因此可以继续在VSCode中调试代码。
按调试快捷键F5,调试器选项将首次弹出:
选择LLDB,将弹出一个错误对话框:
因为我们没有提供相应的配置文件来告诉VSCode要调试哪个可执行文件。
单击[OK]后,VSCode将自动生成.VSCode/启动器。json文件。内容如下:
将程序项目更改为可执行程序的完整路径:
“程序”:”F:/tmp/cmake/demo/build/myapp/Debug/myapp.exe”
然后再次按F5,这一次可以正确执行:
此时,您可以在mylib中设置断点。c或myapp。c. 然后逐步执行程序:
600学习网 » cmake基础示例:如何编译【跨平台】的动态库和应用程序-600学习网