一、前言

我们在写应用程序的过程中,经常需要面对一个开发场景:编写跨平台的应用程序。

这种要求对于 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语言版本的更多相关文章

  1. 应用程序框架实战十七:DDD分层架构之值对象(层超类型篇)

    上一篇介绍了值对象的基本概念,得到了一些朋友的支持,另外也有一些朋友提出了不同意见.这其实是很自然的事情,设计本来就充满了各种可能性,没有绝对正确的做法,只有更好的实践.但是设计与实践的好与坏,对于不 ...

  2. 使用Nginx负载均衡搭建高性能.NETweb应用程序(转)

    一.遇到的问题 当我们用IIS服务器部署了一个web应用以后,当很多用户高并发访问的时候,客户端响应就会很慢,客户的体验就会很差,由于IIS接受到客户端请求的时候,就会创建一个线程,当线程达到几千个时 ...

  3. 一.1搭建跨平台的统一python开发环境

    搭建跨平台的统一python开发环境: 使用开发环境的好处: 可不用在服务器上直接修改源代码---写的代码首先得入版本库(放git或giitlab中),在本地写代码提交到git中.然后在服务器上git ...

  4. 基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序

    特点: 1.基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序: -(IBAction) showTOC:(id)sender { if (_tocViewController ...

  5. 使用Nginx负载均衡搭建高性能.NETweb应用程序二

    在文章<使用Nginx负载均衡搭建高性能.NETweb应用程序一>中,让我们对Nginx有了一个初步认识,下面我们将在windows平台下面使用Nginx演示集群部署我们的web应用. 一 ...

  6. [原创] 分享我们自己搭建的微信小程序开发框架——wframe及设计思想详解

    wframe不是控件库,也不是UI库,她是一个微信小程序面向对象编程框架,代码只有几百行.她的主要功能是规范小程序项目的文件结构.规范应用程序初始化.规范页面加载及授权管理的框架,当然,wframe也 ...

  7. 网络采集软件核心技术剖析系列(7)---如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)

    一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件 ...

  8. Cesium入门2 - Cesium环境搭建及第一个示例程序

    Cesium入门2 - Cesium环境搭建及第一个示例程序 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 验 ...

  9. 跨平台的WebRTC客户端框架:OpenWebRTC

    Webrtc的ios框架编译 http://www.th7.cn/Program/IOS/201502/390418.shtml WebRTC in WebKit : http://www.webrt ...

随机推荐

  1. JWT加密解密方法

    public static string Key { get; set; } = "123456789987654321";//解密串 /// <summary> // ...

  2. Spring 声明式事务与编程式事务详解

    本文转载自IBM开发者论坛:https://developer.ibm.com/zh/articles/os-cn-spring-trans 根据自己的学习理解有所调整,用于学习备查. 事务管理对于企 ...

  3. 一键自签本地 TLSv3 多域名 SAN 域名证书工具 HTTPS(最新版 Chrome 浏览器策略测试通过)

    一键自动生成本地自签名SAN域名证书工具 原生OpenSSL生成自签名SAN CA域名(V3签名),在Linux.MacOS系统下签发测试通过. 用于一键快速生成开发和测试场景证书,内部平台授权和私有 ...

  4. P1177【模板】快速排序(JAVA语言)

    import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; import java.util ...

  5. PTA 带头结点的链式表操作集

    6-2 带头结点的链式表操作集 (20 分)   本题要求实现带头结点的链式表操作集. 函数接口定义: List MakeEmpty(); Position Find( List L, Element ...

  6. RPC 框架设计

    RPC 框架设计 初识 RPC 服务化有什么好处? 防止代码拷贝 防止底层复杂性的扩散 防止公共库的耦合 保证 SQL 的质量,能够解除数据库的耦合 什么是 RPC RPC:Remote Proced ...

  7. 用程序员的思维了解Filecoin

    程序员接触一个新技术惯用步骤: 先搜索引擎搜索一波,找个最简单的解释.如果有了个大概的概念,就前往2.否则循环1->1->1...直到有个大概的概念为止. 上官网跑一遍. 各种论坛社区溜达 ...

  8. 如何配置Nginx,实现http访问重定向到https?

    现在越来越多的网站,当我们输入域名时,会自动重定向到https,我们只需要简单修改下Nginx配置文件/usr/local/nginx/conf/nginx.conf(根据个人的实际存储路径)即可. ...

  9. 茫茫内存,我该如何用 windbg 找到你 ?

    一:背景 1. 讲故事 前天wx上有个朋友丢给我一个dump,让我帮忙鉴定一下某些敏感信息在内存中是否也是加密的,现在数据安全很重要,不仅数据库中的信息要加密,灌到内存后数据同样也需密文存储,随用随解 ...

  10. leetcode 783 二叉搜索树节点最小距离

    PS:(感觉这题名字和内容有歧义) 要求得到任意不同节点值之间的最小差值. 本身二叉树是有序的,又找最小差值,其实就是相当于在一个有序数组中找到每相邻两数之间最小差值. 朴素思想: 中序遍历树,把值都 ...