使用clion+cmake+vcpkg的开发现代的c++跨平台程序

使用c++开发跨平台的程序

背景

在开发过程中,使用c++作为开发语言,通常被认为是痛苦的,啰嗦的,超长开发时间的.最近几年有各种各样的语言被广泛使用,相对比来说c++不是那么出彩.c++虽然年龄大,但是它不是坐以待毙的,它自己也在急剧变革,最近几年,为了方便c++的开发,涌现出非常多的工具.我结合自己的工作经验,打算写点东西,介绍一下.

C++诞生初期解决了很实际的问题,但是随着时代的变革c++遇到了新的情况.

首先就是包依赖管理,c++并没有在这上面有所约束,导致开发在管理依赖包的时候,非常的困难,有时候可以说是一团糟.c++的处境,有点像nuget出现之前的c#,maven出现之前的java.不过现在这个也得到了解决.微软推出了vcpkg.此工具完全解决了这个问题.当然,针对c++包管理,还有其他的工具,此处,我只推荐vcpkg.理由如下:1.它切合了现代c++的开发流程.2.它真的很好的管理了包以及包依赖,以及头文件.3.它易于使用.在开发过程中每个平台的操作方式都是一致的.

其次项目组织方式,c++并没有在这上有所约束.好吧,所处的时代的确没有考虑到未来的情况.我这里选择cmake. 段子 A:我写c++代码, B:具体的工作是? A:你具体指的是写c++代码,写c++代码的代码,以及写c++文件的代码?....虽然是段子,不过cmake就是c++文件的代码.现在也算是c++开发的标配了.

再次开发工具,此处有很多选择,vs和vscode,以及clion.我选择了clion.

最后开发的操作系统,既然是开发跨平台的程序,开发平台也需要选择一下,我选择了win10.没有选择linux桌面系统.理由简单,windows工具太多了.我现在年龄已经很大了.已经过了需要使用操作系统来体现自我逼格的阶段了.我无意争论那个系统好与坏.我现在需要的是生活的时间.(然而码农最缺少的就是时间,其实最主要原因是工作交流都使用win系统)再说以上工具都是跨平台的,完全可以无缝的移植到win或者linux桌面上去.真正的完全无缝.操作方式都不带任何变化的.

总之本文就是使用clion+cmake+vcpkg的开发现代的c++跨平台程序.

项目的基本组织方式

项目是在win10中编写的,我不怕编写东西,我只是怕出了问题,不知道问题所在.所以编译和调试也占据很重要的地位,都是远程操作的.

如果画一个图,可以如下表示.

以上可以看出,除去调试是在windows上以外,其余的编译和调试,都不行在各个平台再进行一遍.实际开发过程中,编译和调试一般只需要远端在linux下进行,win系统一般不需要任何改动.这完完全全得益于cmake和vcpkg(真的是强烈推荐,可以说,如果没有vcpkg,我不会写这个东西).

啰嗦了这么多,现在终于要进入正文了.

环境搭配

Linux环境准备

准备一个linux操作环境,我准备是ubuntu18.04 .

在Ubuntu上安装git,cmake,gcc7.3.0.这三个网上的安装教程多如牛毛.这里就不复述了.现在我把我机器上的安装环境截图如下.

安装vcpkg.

1. 建立一个目录/vcpkg

2. 输入指令git clone https://github.com/microsoft/vcpkg

3. 进入目录/vcpkg,

4. 编译sudo bash ./ bootstrap-vcpkg.sh,会生成一个可执行文件vcpkg,不用安装到任何其他的位置,让它留在生成的地方就好.

5. 定义环境变量 VCPKG_ROOT="/vcpkg"

6. 安装gdb和ssh,这个是clion远程调试要使用的.

Windows环境准备

我使用的是 win10.安装了git,cmake,vs2019.

再安装vcpkg.定义一个环境变量VCPKG_ROOT="/vcpkg"

管理包

现在使用vcpkg安装一些必要的c++包.

比如,我安装了boost包.

vcpkg install boost

查看一下.vcpkg list或者vcpkg list boost,部分截图如下

我只是为了嘚瑟一下而已,列表是在太长了.嘚瑟是程序员的必要需求.

Vcpkg的基本文件结构

vcpkg会在VCPKG_ROOT所指向的目录底下存储所有的包,

linux示意如下.

Windows示意如下

vcpkg主要使用的命令就是

vcpkg search xxxx ##搜索一个特定的c++库

vcpkg list xxxx ##显示已经安装的c++库.

vcpkg install xxxx ##安装一个特定的库

如果某个库文件有,而vcpkg没有收录.可以去研究一下ports/ 目录底下的各个文件夹.里面的文件指示vcpkg应该如何搜索特定的包.如果查看大部分portfile.cmake文件,就发现,vcpkg大部分库来自于github.这里只是提提,就不展开了.大家自己研究.

与Clion互动

安装clion,我这里使用的是2019.1.3版本.安装就不复述了.废话一句就是,有钱捧钱场,没钱的捧人场.

我们使用vcpkg安装好了各种库,目的是为了方便的使用,让vcpkg帮我们管理各种各样的头文件啥的.我们只需要放肆的编写bug,嗯…我们只需要专注于实现业务逻辑.这一切有一个统一的界面呈现给我们,这个界面就是clion.

如果要添加一个新的库文件一般就是如下流程

vcpkg install xxxx ----àclion更新cmake-à放肆的使用新安装的库.-à编译-à调试.

以上各个步骤,第一步需要手动输入一个指令外,第二步需要更改一点cmake文件.除去以上步骤以外,剩余的所有步骤都不需要手动干预.这在vcpkg出现之前是不敢想象的.之前光引入头文件就劝退了多少人呀.如果再加上编译,连接库文件等等动作…c++又名c艹是非常有道理的.

现在第一步手动输入指令与第二步更改cmake文件,应该都不算是负担了,如果还觉得是负担,可以说只能等AI自动编程来拯救了.(我用脸滚了一晚上键盘,编写处理新一代操作系统windoors,不是梦).

下面通过一个简单的项目把项目建立到调试,再过具体一点.

Hello world

现在的主角就要转向clion了.我打算建立一个简单的c++程序,这个程序可以在linux上编译调试,同时也可以在win上编译调试.

我使用clion建立了一个新项目,截图如下

以下,是我的编译工具链的设置.找到菜单 File->Settings->Build,Execution->Toolchains.截图如下

找到File->Settings-> Build,Execution->Deployment.配置一个远程linux主机.截图如下

因为要远程编译,必然的要把本地的源代码传送到远端linux里去.这里就是指示clion如何对应本地项目目录和远端目录的.其中Mapping指定了如何对应.大家可以根据自己的需要设置.下图我设置成立项目根目录对应着/root/clionproject/test/.

更改以上两个,下面要配置clion当中的cmake了.这里才是真正使得clion和vcpkg互动起来.找到File->Settings-> Build,Execution->CMake,在ToolChain选择我们刚刚设置的工具链之一.

其中CMake options要填入:

-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake

这样vcpkg就可以和clion互动起来了.clion使用vcpkg.cmake文件,此文件会指导cmake来寻找vcpkg管理的各种库文件,并指导clion使用它们.

依照同样的方式创造一下配置,使得clion也可以在vs下编译此程序.

下面我编写一个简单的hellow world程序,此程序使用boost,编写一次,分别在linux和windows下编译(一次编写,处处编译),并打印出此时的操作系统类型.

1. 在Clion中创建一个新的项目:略

2. 添加Boost库到项目中

使用以上配置使得条件boost库变的简单.

在CMakeLists.txt中编辑如下内容

3. 添加业务逻辑

里面有两个文件main.cpp.

OperationSystem.hpp

逻辑都超级简单,就不复述了.

4. 最后编译.只需要选择配置,然后点击编译就可以了.截图如下

以上截图是linux,windows也是一样的.就不截图了.

一次编辑,处处编译

考虑以上过程,如果一套代码你再一台机器编辑好.比如在windows编辑好.然后复制到linux底下编译一下,有没有需要更改的地方?从以下几个方面检查一下

Cmake:一套配置文件在linux和windows底下是相同的,不用更改.

依赖库:都统一使用vcpkg管理依赖库.在linux和windows下是相同的,也不用更改.

项目代码:也不用更改.

编译命令:都是cmake自动操作的.也是一样的.

发现:基本上做到了一次编辑,处处编译.由于c++历史的原因,想要完全做到此特点,也着实难办.对于一些特殊的需求,特别是硬件需求,低层需求,还是要使用预编译符号或者cmake来针对不同操作系统,区别对待.虽然不能不能做到如netcore一样真正一次编辑处处编译.毕竟那是有大厂支持的.可以说,通过以上的介绍,基本上实现了”一次编辑,处处编译”.一套代码中只有非常少量的几行代码需要针对操作系统特殊处理.

另一个由”处处编译”带来的好处就是可以自动打包.通过git上传代码至代码库,然后在目标机器中使用自动打包工具自动编译.

C++工具

格式化工具

Clion内置了一个clang格式化工具.可以使用它来格式化自己的代码.这个不多赘述了.

内存泄漏

很多语言都内置了自动垃圾回收所谓GC,比如net,go等.但是有很多时候,由于设备或者效率的要求,使得运行环境不适合GC.但是内存回收依然十分的重要.而C++的内存泄露却总是使得各位码农花费很多时间去避免.如剃刀一般剃光了很多人的头发.

C++发展了很多工具,来避免内存泄露,如智能指针.但是由于库或者历史的原因,使得智能指针不能覆盖全部代码.现在有工具来解决这个问题了.有时候,我总是觉得,造东西不怕,我是怕出问题了却不知道在哪(所以测试很重要).谷歌出了一套工具可以侦测内存泄露.名字叫做sanitizers.

下面我先截图一下,看看如果发生了内存泄露大约给出一个什么样子的提示:

在上图中可以发现,在程序退出的时候,它打印了一些信息,明确的指出哪里(具体到了行)泄露了,泄露了多少字节.由于GCC内置了这个sanitizers.所以这里我直接使用了GCC内置的sanitizers.

下面我将使用此sanitizers.

程序很简单,我改造main.cpp,截图如下

上段申请了一段内存并没有释放.

在cmake文件中添加以下一句

SET(CMAKE_CXX_FLAGS "-fsanitize=address")

它目的就是告诉编译器,增加一个flag sanitize=address .

现在我在linux环境中编译运行,得到如下截图.

可是问题来了.如果同样的代码在windows底下运行,就会获得如下错误.

好在内存泄露的检查只需要一次就好.所以我一般就修改cmake,使得它只会在gcc编译器下使用sanitize.而在msvc下就不使用此flag.不要乱立flag.

在程序结束的时候报告内存泄露的位置,msvc很早之前就有了.可以参考此文章. https://docs.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019

同时,如果使用 clang-cl来替代cl.也可以使用sanitize,但是有某些功能上的限制.如果详细查看微软的文章,就会发现,其实微软的CRT内存泄露侦测,更灵活全面.功能更强大.

以上代码都是简单的演示,代码逻辑非常简单.源码我就不上了.有心实验者按照图片自己稍微敲敲吧.

谷歌的sanitize还有一个ThreadSanitizer,专门用来检测资源竞争和死锁的.使用也是一样的.

使用clion+cmake+vcpkg的开发现代的c++跨平台程序的更多相关文章

  1. clion结合vcpkg以及GTest的使用

    目录 一.vcpkg简介.下载和使用 1. vcpkg是什么 2. vcpkg下载 3. 使用vcpkg下载第三方库 二.clion结合vcpkg 1. 方法一:使用环境变量 2. 方法二:添加cma ...

  2. CLion远程调试嵌入式开发板程序

    CLion远程调试嵌入式开发板程序 目录 CLion远程调试嵌入式开发板程序 1. 目的 2. 前提条件 3. CLion设置 3.1 设置一个Deployment 3.2 上传需要的目录到目标板子 ...

  3. TODO:即将开发的第一个小程序

    TODO:即将开发的第一个小程序 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验.个人理解小程序是寄宿在微信平台上的一个前端框架,具有跨平台功能, ...

  4. 基于 SailingEase WinForm Framework 开发优秀的客户端应用程序(目录)

    本系统文章将详细阐述客户端应用程序的设计理念,实现方法. 本系列文章以  SailingEase WinForm Framework 为基础进行设计并实现,但其中的设计理念及方法,亦适用于任何类型的客 ...

  5. ASP.NET Core 中文文档 第二章 指南(8) 使用 dotnet watch 开发 ASP.NET Core 应用程序

    原文:Developing ASP.NET Core applications using dotnet watch 作者:Victor Hurdugaci 翻译:谢炀(Kiler) 校对:刘怡(Al ...

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

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

  7. 使用VS Code开发ASP.NET Core 应用程序

    最新教程:http://www.cnblogs.com/linezero/p/VSCodeASPNETCore.html 使用VS Code开发ASP.NET Core 应用程序 准备 1.安装VS ...

  8. BizTalk开发系列(二) "Hello World" 程序搬运文件

    我们在<QuickLearn BizTalk系列之"Hello World">里讲到了如何快速的开发第一个BizTalk 应用程序.现在我们来讲一下如何把这个程序改成用 ...

  9. SNF开发平台WinForm之十一-程序打包-SNF快速开发平台3.3-Spring.Net.Framework

    原来我们用的是微软自带的打包工具去打包,但感觉好像也是第三方做的打包并且很是麻烦,还有时不成功报错.那综合考虑就找一个简单实用的打包工具吧,就找到了NSIS这个.具体打包步骤如下: 1.安装NSIS ...

随机推荐

  1. 互联网UV,PU,TopN统计

    1. UV.PV.TopN概念 1.1 UV(unique visitor) 即独立访客数 指访问某个站点或点击某个网页的不同IP地址的人数.在同一天内,UV只记录第一次进入网站的具有独立IP的访问者 ...

  2. 《团队作业第三、四周》五阿哥小组Scrum 冲刺阶段---Day2

    <团队作业第三.四周>五阿哥小组Scrum 冲刺阶段---Day2 一.项目燃尽图 二.项目进展 20182310周烔今日进展: 主要任务一览:完成总博客的提交,制定接下来的计划,编写博客 ...

  3. Python实现描述性统计

    该篇笔记由木东居士提供学习小组.资料 描述性统计的概念很好理解,在日常工作中我们也经常会遇到需要使用描述性统计来表述的问题.以下,我们将使用Python实现一系列的描述性统计内容. 有关python环 ...

  4. 线程池的使用(ThreadPoolExecutor详解)

    为什么要使用线程池? 线程是一个操作系统概念.操作系统负责这个线程的创建.挂起.运行.阻塞和终结操作.而操作系统创建线程.切换线程状态.终结线程都要进行CPU调度——这是一个耗费时间和系统资源的事情. ...

  5. 坑:jmeter部署AWS云服务器时出现连接超时Non HTTP response code: org.apache.http.conn.HttpHostConnectException

    背景: jmeter脚本部署到云服务器(AWS EC2)公网上时,启动jmeter脚本运行了5个小时才运行完毕,后面发现脚本报错timeout(如图),找了很久不知道原因,后面进入脚本发现全部在报错. ...

  6. Alibaba Nacos:搭建Nacos平台

    1.下载安装包 https://github.com/alibaba/nacos/releases 往下翻,找到压缩包下载. 2.解压 tar -xvf nacos-server-$version.t ...

  7. Shell脚本实现对文件编辑

    常见Linux文件的编辑命令 vi/vim,有时候我们想写一个脚本实现对文件编辑,这个时候,可能就不够用了,下面介绍一些办法 1.echo命令 Shell的echo命令常用于字符串的输出 例如: [r ...

  8. px,em和rem

    1 px像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的 2 em是相对长度单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字 ...

  9. rust控制流

    fn main() { let number = 6; if number % 4 == 0 { println!("number is divisible by 4"); } e ...

  10. MySQL免安装配置步骤

    此方式为直接解压压缩包安装MySQL 1.下载相关压缩包 官网下载地址:https://dev.mysql.com/downloads/mysql/ 下载后将压缩包解压至自己想要的文件路径即可 2.新 ...