使用clion+cmake+vcpkg的開發現代的c++跨平臺程序

使用clion+cmake+vcpkg的開發現代的c++跨平臺程序java

使用c++開發跨平臺的程序

背景

在開發過程當中,使用c++做爲開發語言,一般被認爲是痛苦的,囉嗦的,超長開發時間的.最近幾年有各類各樣的語言被普遍使用,相對比來講c++不是那麼出彩.c++雖然年齡大,可是它不是坐以待斃的,它本身也在急劇變革,最近幾年,爲了方便c++的開發,涌現出很是多的工具.我結合本身的工做經驗,打算寫點東西,介紹一下.linux

C++誕生初期解決了很實際的問題,可是隨着時代的變革c++遇到了新的狀況.c++

首先就是包依賴管理,c++並無在這上面有所約束,致使開發在管理依賴包的時候,很是的困難,有時候能夠說是一團糟.c++的處境,有點像nuget出現以前的c#,maven出現以前的java.不過如今這個也獲得瞭解決.微軟推出了vcpkg.此工具徹底解決了這個問題.固然,針對c++包管理,還有其餘的工具,此處,我只推薦vcpkg.理由以下:1.它切合了現代c++的開發流程.2.它真的很好的管理了包以及包依賴,以及頭文件.3.它易於使用.在開發過程當中每一個平臺的操做方式都是一致的.git

其次項目組織方式,c++並無在這上有所約束.好吧,所處的時代的確沒有考慮到將來的狀況.我這裏選擇cmake. 段子 A:我寫c++代碼, B:具體的工做是? A:你具體指的是寫c++代碼,寫c++代碼的代碼,以及寫c++文件的代碼?....雖然是段子,不過cmake就是c++文件的代碼.如今也算是c++開發的標配了.程序員

再次開發工具,此處有不少選擇,vs和vscode,以及clion.我選擇了clion.github

最後開發的操做系統,既然是開發跨平臺的程序,開發平臺也須要選擇一下,我選擇了win10.沒有選擇linux桌面系統.理由簡單,windows工具太多了.我如今年齡已經很大了.已通過了須要使用操做系統來體現自我逼格的階段了.我無心爭論那個系統好與壞.我如今須要的是生活的時間.(然而碼農最缺乏的就是時間,其實最主要緣由是工做交流都使用win系統)再說以上工具都是跨平臺的,徹底能夠無縫的移植到win或者linux桌面上去.真正的徹底無縫.操做方式都不帶任何變化的.編程

總之本文就是使用clion+cmake+vcpkg的開發現代的c++跨平臺程序.bootstrap

項目的基本組織方式

項目是在win10中編寫的,我不怕編寫東西,我只是怕出了問題,不知道問題所在.因此編譯和調試也佔據很重要的地位,都是遠程操做的.ubuntu

若是畫一個圖,能夠以下表示.c#

clip_image002[9]

以上能夠看出,除去調試是在windows上之外,其他的編譯和調試,都不行在各個平臺再進行一遍.實際開發過程當中,編譯和調試通常只須要遠端在linux下進行,win系統通常不須要任何改動.這完徹底全得益於cmake和vcpkg(真的是強烈推薦,能夠說,若是沒有vcpkg,我不會寫這個東西).

囉嗦了這麼多,如今終於要進入正文了.

環境搭配

Linux環境準備

準備一個linux操做環境,我準備是ubuntu18.04 .

在Ubuntu上安裝git,cmake,gcc7.3.0.這三個網上的安裝教程多如牛毛.這裏就不復述了.如今我把我機器上的安裝環境截圖以下.

clip_image004[10]

安裝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

clip_image006[9]

查看一下.vcpkg list或者vcpkg list boost,部分截圖以下

clip_image008[9]

clip_image010[9]

我只是爲了嘚瑟一下而已,列表是在太長了.嘚瑟是程序員的必要需求.

Vcpkg的基本文件結構

vcpkg會在VCPKG_ROOT所指向的目錄底下存儲全部的包,

linux示意以下.

clip_image012[9]

Windows示意以下

clip_image014[9]

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創建了一個新項目,截圖以下

clip_image016[9]

如下,是個人編譯工具鏈的設置.找到菜單 File->Settings->Build,Execution->Toolchains.截圖以下

clip_image018[9]

找到File->Settings-> Build,Execution->Deployment.配置一個遠程linux主機.截圖以下

clip_image020[9]

由於要遠程編譯,必然的要把本地的源代碼傳送到遠端linux裏去.這裏就是指示clion如何對應本地項目目錄和遠端目錄的.其中Mapping指定了如何對應.你們能夠根據本身的須要設置.下圖我設置成立項目根目錄對應着/root/clionproject/test/.

clip_image022[9]

更改以上兩個,下面要配置clion當中的cmake了.這裏纔是真正使得clion和vcpkg互動起來.找到File->Settings-> Build,Execution->CMake,在ToolChain選擇咱們剛剛設置的工具鏈之一.

 clip_image024[9]

其中CMake options要填入:

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

這樣vcpkg就能夠和clion互動起來了.clion使用vcpkg.cmake文件,此文件會指導cmake來尋找vcpkg管理的各類庫文件,並指導clion使用它們.

依照一樣的方式創造一下配置,使得clion也能夠在vs下編譯此程序.

clip_image026[9]

下面我編寫一個簡單的hellow world程序,此程序使用boost,編寫一次,分別在linux和windows下編譯(一次編寫,到處編譯),並打印出此時的操做系統類型.

1. 在Clion中建立一個新的項目:略

2. 添加Boost庫到項目中

使用以上配置使得條件boost庫變的簡單.

在CMakeLists.txt中編輯以下內容

clip_image028[9]

3. 添加業務邏輯

裏面有兩個文件main.cpp.

clip_image030[9]

OperationSystem.hpp

clip_image032[9]

邏輯都超級簡單,就不復述了.

4. 最後編譯.只須要選擇配置,而後點擊編譯就能夠了.截圖以下

clip_image034[10]

以上截圖是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.

下面我先截圖一下,看看若是發生了內存泄露大約給出一個什麼樣子的提示:

clip_image036[9]

在上圖中能夠發現,在程序退出的時候,它打印了一些信息,明確的指出哪裏(具體到了行)泄露了,泄露了多少字節.因爲GCC內置了這個sanitizers.因此這裏我直接使用了GCC內置的sanitizers.

下面我將使用此sanitizers.

程序很簡單,我改造main.cpp,截圖以下

clip_image038[9]

上段申請了一段內存並無釋放.

在cmake文件中添加如下一句

SET(CMAKE_CXX_FLAGS "-fsanitize=address")

它目的就是告訴編譯器,增長一個flag sanitize=address .

如今我在linux環境中編譯運行,獲得以下截圖.

clip_image040[9]

但是問題來了.若是一樣的代碼在windows底下運行,就會得到以下錯誤.

clip_image042[9]

好在內存泄露的檢查只須要一次就好.因此我通常就修改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,專門用來檢測資源競爭和死鎖的.使用也是同樣的.

相關文章
相關標籤/搜索