您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關如何使用Cmake管理項目的跨平臺C++應用程序的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
使用Cmake管理項目的跨平臺C++應用程序
MSDN參考文檔:https://docs.microsoft.com/zh-cn/cpp/build/cmake-projects-in-visual-studio?view=msvc-160
CMake對照VS參數修改總結:https://blog.csdn.net/xum2008/article/details/7268761?source=1
使用CMake管理項目,再使用標準C++作為開發語言,就可以創建完全跨平臺的C++應用程序。
1)創建CMake項目
可以從IDE中創建一個新的cmake項目,也可以打開一個已經存在的cmake項目。
要打開存在的cmake項目,從【文件】【打開】【CMake】導入cmake配置:
新建cmake項目,從新建中選擇cmake項目即可。從VS2019的項目解釋可以看出,CMake是作為一個跨平臺的管理工具存在,而不僅僅是Linux項目;
2)切換到CMake視圖,這個很重要,因為默認為文件夾視圖,不方便對子項目分別進行生成等操作:
切換到解決方案視圖,找到這個按鈕,單擊一次:
出現選擇視圖,然后雙擊選中的視圖類型,這里選擇CMake目標視圖,進入CMake開發視圖:
這里就是CMake目標視圖,右鍵單擊項目,可以添加新的目標(即添加新的子項目),全部生成,清理等,同樣單擊某個項目也有類似的操作菜單:
這里解釋下CMake緩存的意思:如果選擇生成緩存,CMake會解析CMakeLists.txt文件,并生成CMake項目視圖;必須這里有exe生成項目,也有dll生成項目,如果清除這些緩存,就只剩下CMakeLists.txt文件了。
需要注意的是,在輸出欄需要選擇不同的輸出來源才能看到CMake過程,大多數默認都是生成輸出來源,如果需要了解CMake的過程,可以切換到CMake來源。
3)添加一個名為Common的動態庫項目:
//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下的動態庫,還需要生成Common.lib文件,因此需要導出動態庫接口:_declspec(dllexport);由于是跨平臺項目,Linux項目無法設置導出接口,需要做宏限制。
注意!有時候當我們添加了宏來限制不同平臺的宏輸出,會發現在選擇了Linux-GCC平臺之后WIN32宏卻被定義了。比如在common.h頭文件中,WIN32顯示已被定義,但是當你編譯到Linux平臺時卻沒有任何問題,甚至還可以調試,只是在某些地方代碼和實際的可能對不上。那是因為IntelliSense(VS智能感知功能)沒有被更新導致。簡單說就是你的VS所在的Windows平臺并沒有得到最新的目標平臺,也就是Linux平臺的相關開發環境。找到【工具】【選項】【跨平臺】,更新下設置的Linux遠程電腦下的IntelliSense,重啟一下VS即可。可打開【瀏覽】功能,找到VS從遠程Linux同步過來的相關依賴文件。
4)在主項目上將Common子項目添加到引用,這一步會重新生成CMake緩存:
因為改變了主項目的CMakeLists.txt文件,增加了target_link_libraries(LinuxCmakeTest "Common")這一欄。這是CMake添加引用項目的方式。
5)完善cmake配置項
# CMakeList.txt: 頂層 CMake 項目文件,在此處執行全局配置 # 并包含子項目。 # #最低cmake版本要求 cmake_minimum_required (VERSION 3.8) #定義項目名稱 project ("LinuxCmakeTest") #設置C++編譯器選項(Linux系統才需要設置) 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() #根據編譯類型指定不同的庫輸出路徑 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}) #將鏈接庫的搜尋目錄設置為庫輸出目錄 link_directories(${LIBRARY_OUTPUT_PATH}) #使用鏈接庫相對路徑(鏈接庫尋找當前目錄) 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") #添加當前目錄為頭文件包含目錄(這里可以設置多個包含路徑) include_directories(.) #添加子目錄(自動加載目錄下的子項目) add_subdirectory("Common") add_subdirectory ("LinuxCmakeTest") #配置安裝選項(設置后才能使用【安裝】菜單功能) install(TARGETS Common DESTINATION LinuxCmakeTest) install(TARGETS LinuxCmakeTest DESTINATION LinuxCmakeTest)
# CMakeList.txt: LinuxCmakeTest 的 CMake 項目,在此處包括源代碼并定義 # 項目特定的邏輯。 # cmake_minimum_required (VERSION 3.8) # 將源代碼添加到此項目的可執行文件。 add_executable (LinuxCmakeTest "LinuxCmakeTest.cpp" "LinuxCmakeTest.h") # 平臺差異化設置 IF (CMAKE_SYSTEM_NAME MATCHES "Linux") # C++線程在Linux系統需要鏈接pthread庫,使用動態庫需要鏈接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 項目,在此處包括源代碼并定義 # 項目特定的邏輯。 # cmake_minimum_required (VERSION 3.8) add_library(Common SHARED "Common.cpp" "Common.h")
給debug和release指定不同的輸出目錄;
將dll和exe都輸出到同一個目錄下,以免exe找不到dll的情況;
將當前CMakeLists.txt文件所在目錄設置為搜尋目錄,就可以直接使用#include "Common/common.h";
使用add_definitions(-DRELEASE -DCPP)預先定義好需要的宏,就可以在IDE中直接得到宏定義(通過IntelliSense智能感知);
如果需要提供安裝功能,添加install命令到CMakeLists.txt文件中,install安裝后的文件少了.ink,.pdb,.exp等額外文件;
如果要滿足多平臺一套代碼,免不了需要在cmake中對不同平臺做不同的設置,跨平臺不是簡單說說那么容易!
每次修改CMakeLists.txt文件之后VS都會自動解析,如果該文件很大,解析需要花費的時間也會越長(體驗不好!!!)
可以通過CMake設置頁面重定向安裝目錄路徑:
到此為止,這個程序已經可以在Windows平臺編譯并輸出結果。但配置到Linux仍需要一些額外的配置才能正確運行。
6)新建Linux平臺下的CMake配置
這里選擇通用的Linux-GCC-Debug,如果是Release則選擇Linux-GCC-Release:
設置遠程調試Linux平臺:
如果遠程沒有安裝高版本cmake文件,VS會自動提示,可以點擊【是】讓VS自動幫忙安裝一個符合要求的cmake版本:
這里需要注意的是,CentOS默認安裝cmake2.8,很舊很舊的版本。使用VS開發Linux至少需要cmake3.8版本以上。
如果一切順利,應該就可以make成功通過并生成到Linux平臺,可以調試運行了。
7)調試代碼
利用VS2019調試Linux平臺下的Release版本代碼沒有成功,應該是不行。
Debug模式下設置程序啟動參數:
點擊【添加調試配置】,會打開一個名叫launch.vs.json的配置文件,在args中配置啟動參數即可,可以寫成一行,也可以寫成多行:
如果Linux平臺安裝了gdbserver的話(參考文檔一的相關說明),可以更改gdb調試方式:"debuggerConfiguration": "gdbserver"為gdbserver類型。
8)其他一些注意事項(專門填坑)
Linux平臺設置最好使用root賬號,否則可能會出現一些和cmake,gcc相關的報錯;
Linux平臺要安裝最新的cmake和gcc,cmake至少要3.8以上,gcc最好是6.0以上,可以通過cmake --version和gcc/g++ --version命令查看;
WIN32宏或者其他宏顯示不正確,通常重新刷新下IntelliSense就正常了;
如果使用【ln -f -s gcc新版 /usr/bin】配置重定向軟鏈接的方式安裝新版本g++,在編譯時可能會出現“ GLIBCXX_3.4.20' not found ”的錯誤提示,那是因為使用了軟鏈接重定向新版本gcc之后,相對應的lib/lib64庫還未覆蓋,仍然鏈接到了舊版本gcc中,參考下面的連接來處理https://my.oschina.net/u/3489228/blog/3082214 或者 https://blog.csdn.net/qingtingmeng/article/details/49863841
VS2019會將用戶的平臺配置寫入到CMakeSettings.json文件中,可以直接修改這里的內容改變輸出路徑。參考MSDN上的說明:https://docs.microsoft.com/zh-cn/cpp/build/cmakesettings-reference?view=msvc-160
默認編譯和安裝的時候都會將原來的文件全部刪除,如果不想這樣做,尤其是安裝了很多必要文件的時候,可以修改配置:將--delete --delete-excluded參數刪除,只保留-t參數。
感謝各位的閱讀!關于“如何使用Cmake管理項目的跨平臺C++應用程序”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。