溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

發(fā)布時(shí)間:2021-10-11 11:04:30 來源:億速云 閱讀:533 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關(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)目的跨平臺(tái)C++應(yīng)用程序

新建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è)按鈕,單擊一次:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

出現(xiàn)選擇視圖,然后雙擊選中的視圖類型,這里選擇CMake目標(biāo)視圖,進(jìn)入CMake開發(fā)視圖:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

這里就是CMake目標(biāo)視圖,右鍵單擊項(xiàng)目,可以添加新的目標(biāo)(即添加新的子項(xiàng)目),全部生成,清理等,同樣單擊某個(gè)項(xiàng)目也有類似的操作菜單:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

這里解釋下CMake緩存的意思:如果選擇生成緩存,CMake會(huì)解析CMakeLists.txt文件,并生成CMake項(xiàng)目視圖;必須這里有exe生成項(xiàng)目,也有dll生成項(xiàng)目,如果清除這些緩存,就只剩下CMakeLists.txt文件了。

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

需要注意的是,在輸出欄需要選擇不同的輸出來源才能看到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緩存:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

因?yàn)楦淖兞酥黜?xiàng)目的CMakeLists.txt文件,增加了target_link_libraries(LinuxCmakeTest "Common")這一欄。這是CMake添加引用項(xiàng)目的方式。

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yī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è)置頁面重定向安裝目錄路徑:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

到此為止,這個(gè)程序已經(jīng)可以在Windows平臺(tái)編譯并輸出結(jié)果。但配置到Linux仍需要一些額外的配置才能正確運(yùn)行。

6)新建Linux平臺(tái)下的CMake配置

這里選擇通用的Linux-GCC-Debug,如果是Release則選擇Linux-GCC-Release:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

設(shè)置遠(yuǎn)程調(diào)試Linux平臺(tái):

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

如果遠(yuǎn)程沒有安裝高版本cmake文件,VS會(huì)自動(dòng)提示,可以點(diǎn)擊【是】讓VS自動(dòng)幫忙安裝一個(gè)符合要求的cmake版本:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

這里需要注意的是,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ù):

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

點(diǎn)擊【添加調(diào)試配置】,會(huì)打開一個(gè)名叫l(wèi)aunch.vs.json的配置文件,在args中配置啟動(dòng)參數(shù)即可,可以寫成一行,也可以寫成多行:

如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序

如果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í)候,可以修改配置:如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序將--delete --delete-excluded參數(shù)刪除,只保留-t參數(shù)。

感謝各位的閱讀!關(guān)于“如何使用Cmake管理項(xiàng)目的跨平臺(tái)C++應(yīng)用程序”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(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)容。

AI