您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序
MSDN參考文檔:https://docs.microsoft.com/zh-cn/cpp/build/cmake-projects-in-visual-studio?view=msvc-160
CMake對(duì)照VS參數(shù)修改總結(jié):https://blog.csdn.net/xum2008/article/details/7268761?source=1
使用CMake管理項(xiàng)目,再使用標(biāo)準(zhǔn)C++作為開發(fā)語言,就可以創(chuàng)建完全跨平臺(tái)的C++應(yīng)用程序。
1)創(chuàng)建CMake項(xiàng)目
可以從IDE中創(chuàng)建一個(gè)新的cmake項(xiàng)目,也可以打開一個(gè)已經(jīng)存在的cmake項(xiàng)目。
要打開存在的cmake項(xiàng)目,從【文件】【打開】【CMake】導(dǎo)入cmake配置:
新建cmake項(xiàng)目,從新建中選擇cmake項(xiàng)目即可。從VS2019的項(xiàng)目解釋可以看出,CMake是作為一個(gè)跨平臺(tái)的管理工具存在,而不僅僅是Linux項(xiàng)目;
2)切換到CMake視圖,這個(gè)很重要,因?yàn)槟J(rèn)為文件夾視圖,不方便對(duì)子項(xiàng)目分別進(jìn)行生成等操作:
切換到解決方案視圖,找到這個(gè)按鈕,單擊一次:
出現(xiàn)選擇視圖,然后雙擊選中的視圖類型,這里選擇CMake目標(biāo)視圖,進(jìn)入CMake開發(fā)視圖:
這里就是CMake目標(biāo)視圖,右鍵單擊項(xiàng)目,可以添加新的目標(biāo)(即添加新的子項(xiàng)目),全部生成,清理等,同樣單擊某個(gè)項(xiàng)目也有類似的操作菜單:
這里解釋下CMake緩存的意思:如果選擇生成緩存,CMake會(huì)解析CMakeLists.txt文件,并生成CMake項(xiàng)目視圖;必須這里有exe生成項(xiàng)目,也有dll生成項(xiàng)目,如果清除這些緩存,就只剩下CMakeLists.txt文件了。
需要注意的是,在輸出欄需要選擇不同的輸出來源才能看到CMake過程,大多數(shù)默認(rèn)都是生成輸出來源,如果需要了解CMake的過程,可以切換到CMake來源。
3)添加一個(gè)名為Common的動(dòng)態(tài)庫項(xiàng)目:
//common.h #pragma once #ifdef _WIN32 #define COMMON_EXPORT _declspec(dllexport) #else #define COMMON_EXPORT #endif // _WIN32 namespace BGI { namespace Common { COMMON_EXPORT void add(int v1, int v2); } }
//common.cpp #include <iostream> #include <chrono> #include <thread> #include "Common.h" using namespace std; namespace BGI { namespace Common { static void threadproc(int* value) { for (int i = 0; i < 10; i++) { *value += 1; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } void add(int v1, int v2) { thread t1(threadproc, &v1); thread t2(threadproc, &v2); t1.join(); t2.join(); cout << "Value[0] = " << v1 << endl; cout << "Value[1] = " << v2 << endl; } } }
添加完成后選擇生成試試。需要注意的是,如果要生成Windows下的動(dòng)態(tài)庫,還需要生成Common.lib文件,因此需要導(dǎo)出動(dòng)態(tài)庫接口:_declspec(dllexport);由于是跨平臺(tái)項(xiàng)目,Linux項(xiàng)目無法設(shè)置導(dǎo)出接口,需要做宏限制。
注意!有時(shí)候當(dāng)我們添加了宏來限制不同平臺(tái)的宏輸出,會(huì)發(fā)現(xiàn)在選擇了Linux-GCC平臺(tái)之后WIN32宏卻被定義了。比如在common.h頭文件中,WIN32顯示已被定義,但是當(dāng)你編譯到Linux平臺(tái)時(shí)卻沒有任何問題,甚至還可以調(diào)試,只是在某些地方代碼和實(shí)際的可能對(duì)不上。那是因?yàn)镮ntelliSense(VS智能感知功能)沒有被更新導(dǎo)致。簡單說就是你的VS所在的Windows平臺(tái)并沒有得到最新的目標(biāo)平臺(tái),也就是Linux平臺(tái)的相關(guān)開發(fā)環(huán)境。找到【工具】【選項(xiàng)】【跨平臺(tái)】,更新下設(shè)置的Linux遠(yuǎn)程電腦下的IntelliSense,重啟一下VS即可??纱蜷_【瀏覽】功能,找到VS從遠(yuǎn)程Linux同步過來的相關(guān)依賴文件。
4)在主項(xiàng)目上將Common子項(xiàng)目添加到引用,這一步會(huì)重新生成CMake緩存:
因?yàn)楦淖兞酥黜?xiàng)目的CMakeLists.txt文件,增加了target_link_libraries(LinuxCmakeTest "Common")這一欄。這是CMake添加引用項(xiàng)目的方式。
5)完善cmake配置項(xiàng)
# CMakeList.txt: 頂層 CMake 項(xiàng)目文件,在此處執(zhí)行全局配置 # 并包含子項(xiàng)目。 # #最低cmake版本要求 cmake_minimum_required (VERSION 3.8) #定義項(xiàng)目名稱 project ("LinuxCmakeTest") #設(shè)置C++編譯器選項(xiàng)(Linux系統(tǒng)才需要設(shè)置) IF (CMAKE_SYSTEM_NAME MATCHES "Linux") MESSAGE(STATUS "Current platform: Linux ") add_compile_options(-std=c++11) SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 ") ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Windows") MESSAGE(STATUS "Current platform: Windows") ELSE () MESSAGE(STATUS "Other platform: ${CMAKE_SYSTEM_NAME}") ENDIF() #根據(jù)編譯類型指定不同的庫輸出路徑 IF (CMAKE_BUILD_TYPE MATCHES "Release") add_definitions(-DRELEASE -DCPP) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/release) ELSE() add_definitions(-DDEBUG -DCPP) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug) ENDIF() #將程序輸出指定到庫輸出路徑 set(EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH}) #將鏈接庫的搜尋目錄設(shè)置為庫輸出目錄 link_directories(${LIBRARY_OUTPUT_PATH}) #使用鏈接庫相對(duì)路徑(鏈接庫尋找當(dāng)前目錄) set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TURE) set(CMAKE_INSTALL_RPATH "$ORIGIN") #添加當(dāng)前目錄為頭文件包含目錄(這里可以設(shè)置多個(gè)包含路徑) include_directories(.) #添加子目錄(自動(dòng)加載目錄下的子項(xiàng)目) add_subdirectory("Common") add_subdirectory ("LinuxCmakeTest") #配置安裝選項(xiàng)(設(shè)置后才能使用【安裝】菜單功能) install(TARGETS Common DESTINATION LinuxCmakeTest) install(TARGETS LinuxCmakeTest DESTINATION LinuxCmakeTest)
# CMakeList.txt: LinuxCmakeTest 的 CMake 項(xiàng)目,在此處包括源代碼并定義 # 項(xiàng)目特定的邏輯。 # cmake_minimum_required (VERSION 3.8) # 將源代碼添加到此項(xiàng)目的可執(zhí)行文件。 add_executable (LinuxCmakeTest "LinuxCmakeTest.cpp" "LinuxCmakeTest.h") # 平臺(tái)差異化設(shè)置 IF (CMAKE_SYSTEM_NAME MATCHES "Linux") # C++線程在Linux系統(tǒng)需要鏈接pthread庫,使用動(dòng)態(tài)庫需要鏈接dl庫 target_link_libraries(LinuxCmakeTest Common pthread dl) ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Windows") target_link_libraries(LinuxCmakeTest Common) ELSE () MESSAGE(STATUS "Other platform: ${CMAKE_SYSTEM_NAME}") ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
# CMakeList.txt: Common 的 CMake 項(xiàng)目,在此處包括源代碼并定義 # 項(xiàng)目特定的邏輯。 # cmake_minimum_required (VERSION 3.8) add_library(Common SHARED "Common.cpp" "Common.h")
給debug和release指定不同的輸出目錄;
將dll和exe都輸出到同一個(gè)目錄下,以免exe找不到dll的情況;
將當(dāng)前CMakeLists.txt文件所在目錄設(shè)置為搜尋目錄,就可以直接使用#include "Common/common.h";
使用add_definitions(-DRELEASE -DCPP)預(yù)先定義好需要的宏,就可以在IDE中直接得到宏定義(通過IntelliSense智能感知);
如果需要提供安裝功能,添加install命令到CMakeLists.txt文件中,install安裝后的文件少了.ink,.pdb,.exp等額外文件;
如果要滿足多平臺(tái)一套代碼,免不了需要在cmake中對(duì)不同平臺(tái)做不同的設(shè)置,跨平臺(tái)不是簡單說說那么容易!
每次修改CMakeLists.txt文件之后VS都會(huì)自動(dòng)解析,如果該文件很大,解析需要花費(fèi)的時(shí)間也會(huì)越長(體驗(yàn)不好?。。。?/p>
可以通過CMake設(shè)置頁面重定向安裝目錄路徑:
到此為止,這個(gè)程序已經(jīng)可以在Windows平臺(tái)編譯并輸出結(jié)果。但配置到Linux仍需要一些額外的配置才能正確運(yùn)行。
6)新建Linux平臺(tái)下的CMake配置
這里選擇通用的Linux-GCC-Debug,如果是Release則選擇Linux-GCC-Release:
設(shè)置遠(yuǎn)程調(diào)試Linux平臺(tái):
如果遠(yuǎn)程沒有安裝高版本cmake文件,VS會(huì)自動(dòng)提示,可以點(diǎn)擊【是】讓VS自動(dòng)幫忙安裝一個(gè)符合要求的cmake版本:
這里需要注意的是,CentOS默認(rèn)安裝cmake2.8,很舊很舊的版本。使用VS開發(fā)Linux至少需要cmake3.8版本以上。
如果一切順利,應(yīng)該就可以make成功通過并生成到Linux平臺(tái),可以調(diào)試運(yùn)行了。
7)調(diào)試代碼
利用VS2019調(diào)試Linux平臺(tái)下的Release版本代碼沒有成功,應(yīng)該是不行。
Debug模式下設(shè)置程序啟動(dòng)參數(shù):
點(diǎn)擊【添加調(diào)試配置】,會(huì)打開一個(gè)名叫l(wèi)aunch.vs.json的配置文件,在args中配置啟動(dòng)參數(shù)即可,可以寫成一行,也可以寫成多行:
如果Linux平臺(tái)安裝了gdbserver的話(參考文檔一的相關(guān)說明),可以更改gdb調(diào)試方式:"debuggerConfiguration": "gdbserver"為gdbserver類型。
8)其他一些注意事項(xiàng)(專門填坑)
Linux平臺(tái)設(shè)置最好使用root賬號(hào),否則可能會(huì)出現(xiàn)一些和cmake,gcc相關(guān)的報(bào)錯(cuò);
Linux平臺(tái)要安裝最新的cmake和gcc,cmake至少要3.8以上,gcc最好是6.0以上,可以通過cmake --version和gcc/g++ --version命令查看;
WIN32宏或者其他宏顯示不正確,通常重新刷新下IntelliSense就正常了;
如果使用【ln -f -s gcc新版 /usr/bin】配置重定向軟鏈接的方式安裝新版本g++,在編譯時(shí)可能會(huì)出現(xiàn)“ GLIBCXX_3.4.20' not found ”的錯(cuò)誤提示,那是因?yàn)槭褂昧塑涙溄又囟ㄏ蛐掳姹緂cc之后,相對(duì)應(yīng)的lib/lib64庫還未覆蓋,仍然鏈接到了舊版本gcc中,參考下面的連接來處理https://my.oschina.net/u/3489228/blog/3082214 或者 https://blog.csdn.net/qingtingmeng/article/details/49863841
VS2019會(huì)將用戶的平臺(tái)配置寫入到CMakeSettings.json文件中,可以直接修改這里的內(nèi)容改變輸出路徑。參考MSDN上的說明:https://docs.microsoft.com/zh-cn/cpp/build/cmakesettings-reference?view=msvc-160
默認(rèn)編譯和安裝的時(shí)候都會(huì)將原來的文件全部刪除,如果不想這樣做,尤其是安裝了很多必要文件的時(shí)候,可以修改配置:將--delete --delete-excluded參數(shù)刪除,只保留-t參數(shù)。
感謝各位的閱讀!關(guān)于“如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。