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