亚洲国产第一_开心网五月色综合亚洲_日本一级特黄特色大片免费观看_久久久久久久久久免观看

Hello! 歡迎來(lái)到小浪云!


使用Cmake生成跨平臺(tái)項(xiàng)目編譯解決方案


項(xiàng)目最近需要在windows平臺(tái)上運(yùn)行,我花了幾周時(shí)間將linux服務(wù)器移植到Windows平臺(tái),目前已能正常運(yùn)行。然而,新的需求出現(xiàn)了,考慮到代碼結(jié)構(gòu)和組織在兩個(gè)平臺(tái)上是分開的,為了能夠同步維護(hù)兩邊的代碼,我們需要一個(gè)跨平臺(tái)的項(xiàng)目編譯解決方案。經(jīng)過(guò)調(diào)研,我們選擇了cmake工具。本文將詳細(xì)介紹使用cmake進(jìn)行生產(chǎn)項(xiàng)目的一些基礎(chǔ)知識(shí)。

一、CMake簡(jiǎn)介 您可能聽說(shuō)過(guò)多種Make工具,例如gnu Make、qt的qmake、微軟的MS nmake、BSD Make(pmake)、Makepp等。這些工具遵循不同的規(guī)范和標(biāo)準(zhǔn),所執(zhí)行的Makefile格式也各不相同。這給跨平臺(tái)軟件的編譯帶來(lái)了挑戰(zhàn):為了在不同平臺(tái)上編譯,必須為每種標(biāo)準(zhǔn)編寫Makefile,這無(wú)疑是一項(xiàng)繁瑣的工作。

CMake正是在此背景下應(yīng)運(yùn)而生的工具:它允許開發(fā)者編寫一種平臺(tái)無(wú)關(guān)的CMakeLists.txt文件來(lái)定制整個(gè)編譯流程,然后根據(jù)目標(biāo)用戶的平臺(tái)生成所需的本地化Makefile和工程文件,如Linux的Makefile或Windowsvisual studio工程。從而實(shí)現(xiàn)“一次編寫,到處運(yùn)行”的目標(biāo)。

1、Linux安裝CMake 在Linux上,可以直接使用yum -y install cmake進(jìn)行安裝,默認(rèn)安裝的版本是CMake 2.8.12。

如果需要使用CMake的最新版本,可以訪問(wèn)CMake官方網(wǎng)站(https://www.php.cn/link/6943317304e0f076bc8f12dc02c48e9b

建議直接使用yum安裝,或者從官方網(wǎng)站下載cmake-3.12.0-rc2-Linux-x86_64.tar.gz。

2、Windows安裝CMake 在Windows上安裝CMake,可以直接從CMake官方網(wǎng)站的下載頁(yè)面獲取,官方提供了msi安裝版本和源代碼,還提供了一些預(yù)編譯的版本。

建議在Windows上使用安裝版本,也可以下載預(yù)編譯的版本cmake-3.12.0-rc2-win64-x64.zip,但需要手動(dòng)設(shè)置環(huán)境變量。

Windows上既有命令行版本也有GUI版本,具體使用哪種版本取決于您的習(xí)慣。

設(shè)置環(huán)境變量的方法為:我的電腦->屬性->高級(jí)系統(tǒng)設(shè)置->環(huán)境變量,然后將CMake的路徑添加到path環(huán)境變量中。

二、CMake初體驗(yàn) 在本節(jié)中,我們假設(shè)已經(jīng)有一個(gè)項(xiàng)目,并編寫好了CMake的配置文件CMakeLists.txt。

1、Windows使用cmake-gui生成項(xiàng)目

使用Cmake生成跨平臺(tái)項(xiàng)目編譯解決方案

如圖所示,在source code處選擇CMakeLists.txt文件所在的路徑,然后在binaries中選擇項(xiàng)目生成的地址,點(diǎn)擊configure,選擇已安裝的編譯器(如vs2015)。

然后點(diǎn)擊生成,在binaries目錄中就會(huì)生成Visual Studio的工程文件,打開工程文件即可開始編譯。

2、Windows使用cmake生成項(xiàng)目 首先配置好環(huán)境變量,然后打開Windows命令行工具,進(jìn)入項(xiàng)目目錄(CMakeLists.txt所在目錄),新建一個(gè)build文件夾(因?yàn)镃Make會(huì)生成許多中間文件,因此新建一個(gè)文件夾,以便需要清理時(shí)直接刪除build文件夾)。

然后執(zhí)行cmake ../

在build目錄中就會(huì)生成Visual Studio的項(xiàng)目文件,Windows上默認(rèn)生成的是Visual Studio項(xiàng)目。如果需要生成其他編譯器的Makefile,則需要使用-G指定編譯器,如下:

cmake -G “MinGW Makefiles” ../

可以使用cmake –help查看可用的編譯器名稱。

生成項(xiàng)目工程文件或Makefile后,就可以使用相應(yīng)的編譯器來(lái)編譯項(xiàng)目了。

3、Linux使用cmake生成項(xiàng)目 在Linux上使用CMake生成項(xiàng)目與上述第2小節(jié)類似。

在CMakeLists.txt所在目錄新建build目錄,在build目錄中執(zhí)行:

cmake ../

就會(huì)在build目錄中生成Makefile文件,然后可以繼續(xù)執(zhí)行make編譯項(xiàng)目。

4、CMake常用指令 cmake [] ( | )

cmake [(-D=)…] -P

cmake –build

[] [– …]

cmake -E […]

cmake –find-package …

三、CMake配置文件語(yǔ)法 1、指定CMake最低版本 cmake_minimum_required (VERSION 2.6)

2、設(shè)置項(xiàng)目名稱 project (LearnCMake)

3、創(chuàng)建可執(zhí)行程序工程(exe) add_executable函數(shù)用于創(chuàng)建一個(gè)可執(zhí)行程序工程。

add_executable( [WIN32] [MAcosX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 …])

如下所示:

add_executable(FirstExecutable hello_world.cpp)

也可以添加多個(gè)源文件到工程中,如下:

add_executable(FirstExecutable main.cpp app_util.h app_util.cpp)

4、創(chuàng)建庫(kù)文件工程(a/so/lib/dll) add_library函數(shù)用于創(chuàng)建一個(gè)庫(kù)文件工程。

add_library( [Static | SHAred | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 …])

如下所示:

add_library(SecondLibrary second_library.cpp)

與add_executable類似,也可以添加多個(gè)源文件。

add_library(SecondLibrary test.cpp app_util.h app_util.cpp)

默認(rèn)生成的是靜態(tài)庫(kù),也可以顯式設(shè)置庫(kù)的類型為靜態(tài)庫(kù)、動(dòng)態(tài)庫(kù)或模塊。BUILD_SHARED_LIBS也可以控制編譯生成的庫(kù)類型。

add_library(SecondLibrary SHARED second_library.cpp)

5、set設(shè)置變量 前兩節(jié)的add_library和add_executable可以添加多個(gè)源文件,但文件多了之后可能會(huì)占用很長(zhǎng)的行,因此我們可以使用set函數(shù)進(jìn)行變量賦值,然后在調(diào)用add_library和add_executable生成項(xiàng)目。

如下所示,效果與前面的示例相同。

set(AppUtilSrcs app_util.h app_util.cpp)

add_executable(FirstExecutable main.cpp ${AppUtilSrcs})

add_library(FirstLibrary test.cpp ${AppUtilSrcs})

使用set函數(shù),還可以對(duì)變量值進(jìn)行累加,如下AppUtilSrcs就代表3個(gè)文件了:

set(AppUtilSrcs app_util.h app_util.cpp)

set(AppUtilSrcs ${AppUtilSrcs} b.cpp)

除了文件名定義,set還用于變量定義

set(CMAKE_CXX_FLAGS_RELEASE “${CMAKE_CXX_FLAGS_RELEASE} /MT”)

6、代碼控制 如果一個(gè)項(xiàng)目很大,文件數(shù)以千計(jì),那么一個(gè)一個(gè)文件添加就太麻煩了,因此CMake使用aux_source_directory函數(shù)來(lái)添加目錄到工程中。

如下所示,將目錄下所有文件賦值給第一個(gè)變量,然后將這個(gè)變量加到工程中。

aux_source_directory(“./pbase/src” pbase_lib_src_files)

add_library(pbase ${pbase_lib_src_files})

除了添加文件目錄外,我們經(jīng)常還需要包含第三方庫(kù)(頭文件、庫(kù)文件)等需求,添加頭文件目錄功能如下:

include_directories函數(shù)用于添加頭文件包含目錄。

include_directories(“../thirdparty/googletest/googletest/include”)

link_directories函數(shù)用于添加需要鏈接文件的庫(kù)目錄。

link_directories(“../thirdparty/googletest/googletest/lib”)

link_libraries函數(shù)用于添加需要連接的庫(kù)文件。

link_libraries(“protobuf.so”)

鏈接目標(biāo)文件和庫(kù)文件,使用target_link_libraries函數(shù),這里的目標(biāo)文件是指通過(guò)add_executable()和add_library()指令生成的已創(chuàng)建目標(biāo)文件。

target_link_libraries(test lua mysql)

從編譯文件列表中排除文件,可以使用CMake提供的list的REMOVE_ITEM功能來(lái)實(shí)現(xiàn)。

aux_source_directory(src lua_src)

list(REMOVE_ITEM lua_src “src/lua.c” “src/luac.c”)

7、添加編譯選項(xiàng) CMake使用add_compile_options函數(shù)來(lái)添加編譯選項(xiàng),示例如下:

add_compile_options(-std=gnu99)

CMake使用add_definitions函數(shù)為源文件的編譯添加由-D定義的標(biāo)志,示例如下:

add_definitions(-O3 -g -W -Wall -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -D__WUR= -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DTIXML_USE_STL)

注意,這兩個(gè)選項(xiàng)都是針對(duì)所有平臺(tái)、編譯器,因此需要謹(jǐn)慎使用,最好使用if來(lái)進(jìn)行流程處理。

8、添加其他的CMakeLists.txt 一個(gè)CMakeLists.txt里面的target如果要鏈接其他CMakeLists.txt中的target,可以使用add_subdirectory函數(shù),如下所示:

add_subdirectory(“../thirdparty/googletest/googletest/” gtest)

target_link_libraries(gtest)

9、find_package find_package為外部工程加載設(shè)置。

find_package( [version] [EXACT] [QUIET] [[REQUIRED|COMPONENTS] [components…]] [NO_POLICY_SCOPE])

QUIET選項(xiàng)將會(huì)禁掉包沒(méi)有被發(fā)現(xiàn)時(shí)的警告信息。REQUIRED選項(xiàng)表示如果沒(méi)有找到包,CMake的過(guò)程會(huì)終止,并輸出警告信息。

find_package可以根據(jù)CMake內(nèi)置的.cmake腳本查找相應(yīng)的庫(kù)模塊,調(diào)用find_package成功后,會(huì)有相應(yīng)的變量“生成”有效。

例如,調(diào)用find_package(Qt5Widgets)后,返回的變量Qt5Widgets_FOUND和Qt5Widgets_INCLUDE_DIRS就會(huì)生效。然后就可以在CMakeLists.txt中使用上述變量了。

10、條件、循環(huán)控制 If else結(jié)構(gòu)

if(condition) elseif(condition) else() endif()

for循環(huán)

foreach(loop_var arg1 arg2 ...) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endforeach(loop_var)

while循環(huán)

while(condition) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endwhile(condition)

11、Install指令 Install指令用于定義安裝規(guī)則,安裝的內(nèi)容可以包括目標(biāo)二進(jìn)制、動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)以及文件、目錄、腳本等。

參數(shù)中的TARGETS后面跟的就是我們通過(guò)ADD_EXECUTABLE或ADD_LIBRARY定義的目標(biāo)文件,可能是可執(zhí)行二進(jìn)制、動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)。

目標(biāo)類型也就相對(duì)應(yīng)的有三種,ARCHIVE特指靜態(tài)庫(kù),LIBRARY特指動(dòng)態(tài)庫(kù),RUNTIME特指可執(zhí)行目標(biāo)二進(jìn)制。

INSTALL(TARGETS targets... [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION <dir>] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [OPTIONAL] ] [...])

示例如下:

INSTALL(TARGETS myrun mylib mystaticlib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION libstatic )

上面的例子會(huì)將:

可執(zhí)行二進(jìn)制myrun安裝到${CMAKE_INSTALL_PREFIX}/bin目錄

動(dòng)態(tài)庫(kù)libmylib安裝到${CMAKE_INSTALL_PREFIX}/lib目錄

靜態(tài)庫(kù)libmystaticlib安裝到${CMAKE_INSTALL_PREFIX}/libstatic目錄

特別注意的是,您不需要關(guān)心TARGETS具體生成的路徑,只需要寫上TARGETS名稱就可以了。

我的博客即將搬運(yùn)同步至php中文網(wǎng)+社區(qū),邀請(qǐng)大家一同入駐:https://www.php.cn/link/9fe06b33ea459f011178ef3156ff09c7

相關(guān)閱讀