c++項(xiàng)目構(gòu)成從cmake使用基礎(chǔ)詳解
c++項(xiàng)目構(gòu)成及cmake使用基礎(chǔ)知識
c++項(xiàng)目構(gòu)成
c++項(xiàng)目代碼目錄組成
一個(gè)良好的代碼目錄結(jié)構(gòu)如下
為何需要注意代碼的目錄結(jié)構(gòu)
一個(gè)良好的代碼目錄有助于代碼的管理以及項(xiàng)目的共享。如果所有代碼的頭文件以及相應(yīng)的實(shí)現(xiàn)源文件在一個(gè)文件夾下面使得項(xiàng)目較為混亂,長時(shí)間后項(xiàng)目的創(chuàng)建者自己都難以理清,更不用說別人進(jìn)行理解。
各組成部分詳解
- 以上圖為例,該項(xiàng)目的名稱為test2。
- 項(xiàng)目的頭文件放在include文件夾下。
- 項(xiàng)目的源文件(大部分為頭文件的實(shí)現(xiàn))放在src文件夾下。項(xiàng)目的主函數(shù)(實(shí)現(xiàn)項(xiàng)目的功能)為main.cpp。
- 項(xiàng)目的最頂層的cmake文件為CMakeList.txt。
- build文件夾是為了防止cmake執(zhí)行后產(chǎn)生的文件使得項(xiàng)目的目錄變得混亂而創(chuàng)建文件夾。
- .vscode是vscode所產(chǎn)生的,可以放一些vscode的配置文件(使得vscode進(jìn)行項(xiàng)目的調(diào)試更加方便等作用)。
C++編譯鏈接
編譯各個(gè)cpp文件
- 一個(gè)c++程序的各個(gè)部分可以放在不同的cpp文件中,每個(gè)cpp文件之間都是相對獨(dú)立的,只要知道相應(yīng)聲明就能可以進(jìn)行編譯。形成.o文件。
- 鏈接使得程序的各個(gè)部分相互協(xié)作起來完成程序的功能,即將生成的各個(gè).o文件進(jìn)行鏈接形成一個(gè)可執(zhí)行文件。
c++項(xiàng)目中常見文件及其關(guān)系
頭文件(.h結(jié)尾)
- 頭文件中主要是變量的聲明,函數(shù)名的聲明,類的定義(相關(guān)行為的實(shí)現(xiàn)一般在源文件中編寫,比如內(nèi)聯(lián)函數(shù)就可在頭文件中實(shí)現(xiàn)),各種宏定義等。如果我們復(fù)用別人的代碼,如ncnn中的某些數(shù)據(jù)結(jié)構(gòu),某些函數(shù)時(shí),需要包含別人的頭文件。這樣編譯器才知道這是什么意思。
- include是一個(gè)預(yù)編譯命令,將相應(yīng)頭文件的內(nèi)容復(fù)制進(jìn)相應(yīng)文件,使得編譯器知道這是個(gè)啥。
include < headfilepatch>這種尖括號形式搜索路徑順序
編譯器設(shè)置的頭文件查找路徑,編譯器有默認(rèn)的查找路徑,也可以使用I顯示指定
系統(tǒng)路徑
include "headfilepatch"這種雙引號的形式搜索路徑順序
當(dāng)前源文件的所在工作目錄
編譯器設(shè)置的頭文件查找路徑,編譯器有默認(rèn)的查找路徑,也可以使用I顯示指定
系統(tǒng)路徑
兩種include的主要注意點(diǎn)
- 對于名字不沖突的,使用兩種均可(標(biāo)準(zhǔn)庫文件只要不和自定義文件名字沖突,兩種方式都能找到),對于名字沖突的,使用雙引號,就會(huì)優(yōu)先使用自定義的,故復(fù)用別人代碼注意名字沖突的問題。
- 使用I指定搜索路徑的使用,使得搜索路徑的可掌握性。
- 養(yǎng)成良好的include習(xí)慣,防止出現(xiàn)所包含的頭文件和自己想象的不一樣,尤其是自定義的頭文件可能存在沖突時(shí)源文件(.cpp結(jié)尾)
源文件
- 主要是對函數(shù)的實(shí)現(xiàn)
庫(.so或者.a結(jié)尾)
- 庫是別人的可復(fù)用代碼編譯形成目標(biāo)文件集合,可以將其編譯成靜態(tài)庫或者動(dòng)態(tài)庫,與一般的編譯產(chǎn)生的.o文件一樣,最后是要鏈接到程序中的。
- 靜態(tài)庫(.a),在運(yùn)行之前就會(huì)將靜態(tài)庫相關(guān)目標(biāo)文件鏈接到最終的可執(zhí)行文件中,使得程序運(yùn)行是不需要依賴庫。會(huì)產(chǎn)生同樣的目標(biāo)文件在程序多處存在的問題,使得最終可執(zhí)行文件較大且?guī)斓母螺^為苦難。
- 動(dòng)態(tài)庫(.so)在運(yùn)行時(shí)才被鏈接,使得程序運(yùn)行時(shí)依賴庫。但其節(jié)約內(nèi)存,且動(dòng)態(tài)庫的更新相對容易。
cmake使用基礎(chǔ)知識
什么是cmake
- camke是一個(gè)跨平臺(tái)的編譯工具,使得可以使用簡單的語法描述一個(gè)項(xiàng)目的編譯過程(先編譯哪些源文件,哪些編譯成靜態(tài)庫,哪些編譯成動(dòng)態(tài)庫,編譯目標(biāo)放在哪里等等)。
為何使用cmake
- 一個(gè)良好的c++程序由很多的源文件組成,當(dāng)文件數(shù)量較少時(shí)可以較為方便且快速地手工一個(gè)一個(gè)分別編譯然后鏈接起來。但當(dāng)文件數(shù)量變多后,每次都手工一個(gè)個(gè)編譯文件就非常繁瑣。比如一個(gè)c++項(xiàng)目中由兩個(gè).cpp文件時(shí),編譯命令的參數(shù)只用輸入兩個(gè),此時(shí)就算從頭分別編譯也較為方便,但當(dāng)項(xiàng)目由上百個(gè).cpp文件構(gòu)成時(shí),如果還是使用命令進(jìn)行編譯,則會(huì)非常繁瑣。而使用cmake可以將編譯參數(shù)寫下,使得可重復(fù)使用,極大簡化編譯過程。
- 且當(dāng)一個(gè)c++項(xiàng)目的編譯過程較為復(fù)雜時(shí),比如哪些編譯為靜態(tài)庫,哪些編譯為動(dòng)態(tài)庫,編譯輸出位置及其間的關(guān)系是什么樣的等,將項(xiàng)目共享給其它人時(shí),被共享者需要知道上述信息,如果項(xiàng)目作者沒有使用一種簡單的方式提供上述信息,將花費(fèi)許多不必要的精力在項(xiàng)目編譯上。而cmake使得使用簡單的語法就可以描述項(xiàng)目的編譯過程,使得被共享者知道編譯信息且只需要使用make命令就能實(shí)現(xiàn)項(xiàng)目的編譯,使得項(xiàng)目易于共享。
- 使用cmake可以使得一個(gè)c++項(xiàng)目根據(jù)不同平臺(tái)生成相應(yīng)的代碼版本。同時(shí)可以有效控制一個(gè)大型項(xiàng)目中某個(gè)單元的修改后重新編譯、測試等過程,使得大型項(xiàng)目的開發(fā)、調(diào)試、發(fā)布更加高效且便利。
如何使用cmake
- 使用cmake的大致過程為:編寫cmakelists;創(chuàng)建build文件保證項(xiàng)目整潔度;進(jìn)入build文件夾執(zhí)行cmake及make命令完成編譯得到結(jié)果。
一個(gè)簡單的cmakelists如下
一個(gè)經(jīng)過簡單代碼分類組織的c++項(xiàng)目編譯過程需要知道項(xiàng)目的頭文件,源文件,庫生成、庫鏈接等信息。上圖所示cmake可以有效描述并控制實(shí)現(xiàn)該編譯過程。
cmake_minimum_required(version 版本號)
是指定cmake的最低版本號,每個(gè)cmakelists一般都有這條命令。project(項(xiàng)目名稱)
是指定項(xiàng)目名稱。set(var [value])
set命令用于顯示定義變量。圖中用于添加編譯選項(xiàng)(包括顯示警告、生成可調(diào)試目標(biāo))include_directories()
用于指定項(xiàng)目頭文件目錄。其中用 ${變量名}的方式使用了變量。CMAKE_SOURCE_DIR的值為最外層cmakelists所在目錄。file()
將文件加入到某個(gè)變量中,需要具體到文件名。使得可以用一個(gè)變量代表多個(gè)文件,使得cmake更加簡潔。CMAKE_CURRENT_SOURCE_DIR 的值為當(dāng)前正在處理的cmakelists的目錄。message()
用于在編譯過程中輸出某些信息,以便于更好地掌握編譯過程。add_library(庫名 庫類型 源文件)
用于生成一個(gè)庫。add_executable(目標(biāo)名 源文件)
用于編譯源文件生成可執(zhí)行文件。target_link_libraries(可執(zhí)行文件名 鏈接方式 庫名 )
用與add_executable命令后,實(shí)現(xiàn)可執(zhí)行文件與動(dòng)態(tài)庫的鏈接。
- 當(dāng)編寫好cmakelists后,可以在項(xiàng)目最外層目錄中創(chuàng)建一個(gè)build文件夾以存放編譯生成的中間產(chǎn)物以及可執(zhí)行文件等,以讓項(xiàng)目目錄更加整潔。
接下來就可以執(zhí)行命令完成編譯得到結(jié)果。
- 先進(jìn)入到build文件夾中。執(zhí)行cmake 命令生成makefile。cmake命令需要指定cmakelists所在路徑(故一個(gè)目錄層面中只能有一個(gè)cmakelists)。故在build文件中執(zhí)行cmake .. 因?yàn)閏makelists在build文件夾外面。
- 然后在build中執(zhí)行make命令執(zhí)行makefile啟動(dòng)編譯并得到結(jié)果。make命令需要指定makefile所在路徑,由于當(dāng)前操作makefile就在build文件夾中,故此時(shí)只需要執(zhí)行make命令即可。
以上就是c++項(xiàng)目構(gòu)成從cmake使用基礎(chǔ)詳解的詳細(xì)內(nèi)容,更多關(guān)于c++ cmake項(xiàng)目構(gòu)成的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之圖書借閱系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言數(shù)據(jù)結(jié)構(gòu)之圖書借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C語言實(shí)現(xiàn)紙牌24點(diǎn)小游戲
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)紙牌24點(diǎn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10C語言數(shù)據(jù)結(jié)構(gòu)圖的創(chuàng)建與遍歷實(shí)驗(yàn)示例
這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)圖的創(chuàng)建與遍歷實(shí)驗(yàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06C語言去除相鄰重復(fù)字符函數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C語言去除相鄰重復(fù)字符函數(shù)的實(shí)現(xiàn)方法的相關(guān)資料,實(shí)現(xiàn)去重字符串相鄰重復(fù)的字符,不相鄰的不用去重的功能,需要的朋友可以參考下2017-08-08