使用 cmake 来搭建跨平台的应用程序框架:C语言版本
一、前言
我们在写应用程序的过程中,经常需要面对一个开发场景:编写跨平台的应用程序。
这种要求对于 Linux 系列的平台来说,还是比较好处理的,大部分情况下只需要换一个交叉编译工具链即可,涉及到硬件平台相关部分再嵌入几个内联汇编。
但是,对于 Windows 平台来说,就稍微麻烦一些。你可能会说,在 Windows 平台上用 cygwin, minGW 也可以统一编译啊,但是你能指望客户在安装你的程序时,还需要去部署兼容 Linux 的环境吗?最好的解决方式,还是使用微软自家的开发环境,比如VS等等。
这篇文章,我们以一个最简单的程序,来描述如何使用 cmake 这个构建工具,来组织一个跨平台的应用程序框架。
阅读这篇文章,您可以收获下面几个知识点:
> 1. cmake 在编译库文件、应用程序中的相关指令;
>
> 2. Windows 系统中的动态库导出、导入写法;
>
> 3. 如何利用宏定义来进行跨平台编程;
在公众号后台留言【430】,可以收到示例代码。在 Linux/Windows 系统中可以直接编译、执行,拿来即用。
二、示例代码说明
1. 功能描述
示例代码的主要目的,是用来描述如何组织一个跨平台的应用程序结构。它的功能比较简单,如下图所示:
2. 文件结构
> 1. Common:放置一些开源的第三方库,例如:网络处理,json 格式解析等等;
>
> 2. Application: 应用程序,使用 Utils生成的库;
>
> 3. Uitls:放置一些工具、助手函数,例如:文件处理、字符串处理、平台相关的助手函数等等,最后会编译得到库文件(动态库 libUtils.so、静态库 libUtils.a);
>
> 4. 如果扩展其他模块,可以按照 Utils 的文件结构复制一个即可。
3. cmake 构建步骤
在示例代码根目录下,有一个“总领” CMakeLists.txt 文件,主要用来设置编译器、编译选项,然后去 include 其他文件夹中的 CMakeLists.txt 文件,如下:
4. Utils 目录说明
这个目录的编译输出是库文件:
> Linux 系统:libUtils.so, libUtils.a;
>
> Windows 系统:libUtils.dll, libUtils.lib, libUtils.a;
其中的 CMakeLists.txt 文件内容如下:
目前,代码中只写了一个最简单的函数 getSystemTimestamp(),在可执行应用程序中,将会调用这个函数。
5. Application 目录说明
这个目录的编译输出是:一个可执行程序,其中调用了 libUtils 库中的函数。
CMakeLists.txt 文件内容如下:
三、Linux 系统下操作步骤
1. 创建构建目录 build
$ mkdir build
在一个独立的 build 目录中编译,生成的中间代码不会污染源代码,这样对于使用 git 等版本管控工具来说非常的方便,在提交的时候只需要 ignore build 目录即可,强烈推荐按照这样的方式来处理。
2. 执行 cmake,生成 Makefile
$ cd build
$ cmake ..
3. 编译 Utils 库
$ cd Utils/src
$ make
在 CMakeLists.txt 中的最后部分是安装指令,把产生的库文件和头文件,安装到源码中的 install 目录下。
$ make install
4. 编译可执行程序 Application
Application 使用到了 libUtils.so 库,因此需要手动把 libUtils.so 和头文件,复制到 Application 下面对应的 lib/linux 和 include 目录下。
当然,也可以把这个操作写在 Utils 的安装命令里。
$ cd build/Application/src
$ make
执行生成的可执行程序 main,即可看到输出结果。
四、Widnows 系统下操作步骤
1. 通过 cmake 指令生成 VS 工程
同样的道理,新建一个 build 目录,然后在其中执行 cmake ..
指令,生成 VS 解决方案,我使用的是 VS2019:
2. 编译 Utils 库文件
使用 VS2019 打开工程文件 DemoApp.sln,在右侧的解决方案中,可以看到:
在 libUtils_shared 单击右键,选择【生成】:
此时,在目录 build\Utils\src\Debug 下面,可以看到生成的文件:
3. 编译可执行程序 Application
因为Application需要使用 Utils 生成的库,因此,需要手动把库和头文件复制到 Application 下面的 lib/win32 和 include 目录下。
在 VS 解决方案窗口中,在 main 目标上,单击右键,选择【生成】:
此时,在目录 build\Application\src\Debug 下可以看到生成的可执行程序:
直接单击 main.exe 执行,报错:
需要把 libUtils.dll 动态库文件复制到 main.exe 所在的目录下,然后再执行,即可成功。
五、总结
这篇文章的操作过程主要以动态库为主,如果编译、使用静态库,执行过程是一样一样的。
如果操作过程有什么问题,欢迎留言、讨论,谢谢!
在公众号后台留言【430】,可以收到示例代码。在 Linux/Windows 系统中可以直接编译、执行,拿来即用。
祝您好运!
---------- End ----------
让知识流动起来,越分享,越幸运!
星标公众号,能更快找到我!
Hi~你好,我是道哥,一枚嵌入式开发老兵。
推荐阅读
1. C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻
2. 原来gdb的底层调试原理这么简单
3. 一步步分析-如何用C实现面向对象编程
4. 图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架
5. 都说软件架构要分层、分模块,具体应该怎么做(一)
6. 都说软件架构要分层、分模块,具体应该怎么做(二)
使用 cmake 来搭建跨平台的应用程序框架:C语言版本的更多相关文章
- 应用程序框架实战十七:DDD分层架构之值对象(层超类型篇)
上一篇介绍了值对象的基本概念,得到了一些朋友的支持,另外也有一些朋友提出了不同意见.这其实是很自然的事情,设计本来就充满了各种可能性,没有绝对正确的做法,只有更好的实践.但是设计与实践的好与坏,对于不 ...
- 使用Nginx负载均衡搭建高性能.NETweb应用程序(转)
一.遇到的问题 当我们用IIS服务器部署了一个web应用以后,当很多用户高并发访问的时候,客户端响应就会很慢,客户的体验就会很差,由于IIS接受到客户端请求的时候,就会创建一个线程,当线程达到几千个时 ...
- 一.1搭建跨平台的统一python开发环境
搭建跨平台的统一python开发环境: 使用开发环境的好处: 可不用在服务器上直接修改源代码---写的代码首先得入版本库(放git或giitlab中),在本地写代码提交到git中.然后在服务器上git ...
- 基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序
特点: 1.基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序: -(IBAction) showTOC:(id)sender { if (_tocViewController ...
- 使用Nginx负载均衡搭建高性能.NETweb应用程序二
在文章<使用Nginx负载均衡搭建高性能.NETweb应用程序一>中,让我们对Nginx有了一个初步认识,下面我们将在windows平台下面使用Nginx演示集群部署我们的web应用. 一 ...
- [原创] 分享我们自己搭建的微信小程序开发框架——wframe及设计思想详解
wframe不是控件库,也不是UI库,她是一个微信小程序面向对象编程框架,代码只有几百行.她的主要功能是规范小程序项目的文件结构.规范应用程序初始化.规范页面加载及授权管理的框架,当然,wframe也 ...
- 网络采集软件核心技术剖析系列(7)---如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)
一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件 ...
- Cesium入门2 - Cesium环境搭建及第一个示例程序
Cesium入门2 - Cesium环境搭建及第一个示例程序 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 验 ...
- 跨平台的WebRTC客户端框架:OpenWebRTC
Webrtc的ios框架编译 http://www.th7.cn/Program/IOS/201502/390418.shtml WebRTC in WebKit : http://www.webrt ...
随机推荐
- 11、pass,is,位运算的补充
pass的补充 一般Python的代码是基于:和缩进来实现,Python中规定代码块中必须要有代码才算完整,在没有代码的情况下为了保证语法的完整性可以用pass代替 if 条件: pass else: ...
- Just a Joke HDU - 4969(物理+积分)
题目链接:https://vjudge.net/problem/HDU-4969#author=0 题意:一个人在圆心以V2速度追赶一个以V1的速度进行圆周运动,问在圆心的人能否在不超过D的距离追上他 ...
- Co-prime HDU - 4135
题目链接:https://vjudge.net/problem/HDU-4135#author=0 题意:求在区间[a,b]中有多少个数与n互质. 思路:先看数据范围很大,所以不能枚举.因为互质难求, ...
- 3、Spring教程之IOC创建对象方式
1.通过无参构造方法来创建 1.User.java public class User { private String name; public User() { System.out.printl ...
- fork、exec 和 exit 对 IPC 对象的影响
GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...
- cordova app打包apk签名
首先执行:ionic cordova build android --prod --release,执行完会在以下目录生成apk文件( --prod 用以压缩) 然后使用keytool生成keysto ...
- OO第四单元总结暨OO课程总结
一.第四单元作业总结 本单元的主要任务是对 Uml 图元素进行管理和查询,测试一开始会输入一个静态图,之后会对图中相关内容进行查询. 第13,14次作业 第14次作业新增内容很少,故与第13次作业放在 ...
- JDK8中新日期时间API
它们面临的问题是:可变性:像日期和时间这样的类应该是不可变的.偏移性:Date中的年份是从1900开始的,而月份都从0开始.格式化:格式化只对Date有用,Calendar则不行.此外,它们也不是线程 ...
- jQuery入门看这一篇就够了
一.选择器 1.基本 名称 用法 描述 #id $("#myDiv"); 根据给定的ID匹配一个元素 element $("div"); 根据给定的元素标签名匹 ...
- Crackme_003
功能: 拿到文件,先执行一下.功能如下: 1.nag窗口 会先出现如下nag窗口,持续几秒 2.注册窗口: 出现错误会提示:You Get Wrong Try Again 破解: 1.查壳: 无壳, ...