日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

分享一篇很不错的CMake入门文章,值得收藏细读!

發(fā)布時(shí)間:2023/12/20 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分享一篇很不错的CMake入门文章,值得收藏细读! 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

https://www.hahack.com/codes/cmake/

▌什么是 CMake?

你或許聽(tīng)過(guò)好幾種 Make 工具,例如 GNU Make ,QT 的 qmake ,微軟的 MS nmake,BSD Make(pmake),Makepp,等等。這些 Make 工具遵循著不同的規(guī)范和標(biāo)準(zhǔn),所執(zhí)行的 Makefile 格式也千差萬(wàn)別。這樣就帶來(lái)了一個(gè)嚴(yán)峻的問(wèn)題:如果軟件想跨平臺(tái),必須要保證能夠在不同平臺(tái)編譯。而如果使用上面的 Make 工具,就得為每一種標(biāo)準(zhǔn)寫(xiě)一次 Makefile ,這將是一件讓人抓狂的工作。CMake 就是針對(duì)上面問(wèn)題所設(shè)計(jì)的工具:它首先允許開(kāi)發(fā)者編寫(xiě)一種平臺(tái)無(wú)關(guān)的 CMakeList.txt 文件來(lái)定制整個(gè)編譯流程,然后再根據(jù)目標(biāo)用戶的平臺(tái)進(jìn)一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。從而做到“Write once, run everywhere”。顯然,CMake 是一個(gè)比上述幾種 make 更高級(jí)的編譯配置工具。一些使用 CMake 作為項(xiàng)目架構(gòu)系統(tǒng)的知名開(kāi)源項(xiàng)目有 VTK、ITK、KDE、OpenCV、OSG 等 [1]。在 linux 平臺(tái)下使用 CMake 生成 Makefile 并編譯的流程如下:

  • 編寫(xiě) CMake 配置文件 CMakeLists.txt 。

  • 執(zhí)行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(ccmake 和 cmake 的區(qū)別在于前者提供了一個(gè)交互式的界面)。其中, PATH 是 CMakeLists.txt 所在的目錄。

  • 使用 make 命令進(jìn)行編譯。

  • 本文將從實(shí)例入手,一步步講解 CMake 的常見(jiàn)用法,文中所有的實(shí)例代碼可以在這里找到。如果你讀完仍覺(jué)得意猶未盡,可以繼續(xù)學(xué)習(xí)我在文章末尾提供的其他資源。

    ▌入門(mén)案例:單個(gè)源文件

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo1

    對(duì)于簡(jiǎn)單的項(xiàng)目,只需要寫(xiě)幾行代碼就可以了。例如,假設(shè)現(xiàn)在我們的項(xiàng)目中只有一個(gè)源文件 main.cc ,該程序的用途是計(jì)算一個(gè)數(shù)的指數(shù)冪。

    #include?<stdio.h> #include?<stdlib.h>/***?power?-?Calculate?the?power?of?number.*?@param?base:?Base?value.*?@param?exponent:?Exponent?value.**?@return?base?raised?to?the?power?exponent.*/ double?power(double?base,?int?exponent) {int?result?=?base;int?i;if?(exponent?==?0)?{return?1;}for(i?=?1;?i?<?exponent;?++i){result?=?result?*?base;}return?result; }int?main(int?argc,?char?*argv[]) {if?(argc?<?3){printf("Usage:?%s?base?exponent?\n",?argv[0]);return?1;}double?base?=?atof(argv[1]);int?exponent?=?atoi(argv[2]);double?result?=?power(base,?exponent);printf("%g?^?%d?is?%g\n",?base,?exponent,?result);return?0; }

    ▌編寫(xiě) CMakeLists.txt

    首先編寫(xiě) CMakeLists.txt 文件,并保存在與 main.cc 源文件同個(gè)目錄下:

    #?CMake?最低版本號(hào)要求 cmake_minimum_required?(VERSION?2.8)#?項(xiàng)目信息 project?(Demo1)#?指定生成目標(biāo) add_executable(Demo?main.cc)

    CMakeLists.txt 的語(yǔ)法比較簡(jiǎn)單,由命令、注釋和空格組成,其中命令是不區(qū)分大小寫(xiě)的。符號(hào) # 后面的內(nèi)容被認(rèn)為是注釋。命令由命令名稱、小括號(hào)和參數(shù)組成,參數(shù)之間使用空格進(jìn)行間隔。對(duì)于上面的 CMakeLists.txt 文件,依次出現(xiàn)了幾個(gè)命令:

  • cmake_minimum_required:指定運(yùn)行此配置文件所需的 CMake 的最低版本;

  • project:參數(shù)值是 Demo1,該命令表示項(xiàng)目的名稱是 Demo1 。

  • add_executable:將名為 main.cc 的源文件編譯成一個(gè)名稱為 Demo 的可執(zhí)行文件。

  • ▌編譯項(xiàng)目

    之后,在當(dāng)前目錄執(zhí)行 cmake . ,得到 Makefile 后再使用 make 命令編譯得到 Demo1 可執(zhí)行文件。

    [ehome@xman?Demo1]$?cmake?. --?The?C?compiler?identification?is?GNU?4.8.2 --?The?CXX?compiler?identification?is?GNU?4.8.2 --?Check?for?working?C?compiler:?/usr/sbin/cc --?Check?for?working?C?compiler:?/usr/sbin/cc?--?works --?Detecting?C?compiler?ABI?info --?Detecting?C?compiler?ABI?info?-?done --?Check?for?working?CXX?compiler:?/usr/sbin/c++ --?Check?for?working?CXX?compiler:?/usr/sbin/c++?--?works --?Detecting?CXX?compiler?ABI?info --?Detecting?CXX?compiler?ABI?info?-?done --?Configuring?done --?Generating?done --?Build?files?have?been?written?to:?/home/ehome/Documents/programming/C/power/Demo1 [ehome@xman?Demo1]$?make Scanning?dependencies?of?target?Demo [100%]?Building?C?object?CMakeFiles/Demo.dir/main.cc.o Linking?C?executable?Demo [100%]?Built?target?Demo [ehome@xman?Demo1]$?./Demo?5?4 5?^?4?is?625 [ehome@xman?Demo1]$?./Demo?7?3 7?^?3?is?343 [ehome@xman?Demo1]$?./Demo?2?10 2?^?10?is?1024

    ▌多個(gè)源文件

    ▌同一目錄,多個(gè)源文件

    本小節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo2

    上面的例子只有單個(gè)源文件。現(xiàn)在假如把 power 函數(shù)單獨(dú)寫(xiě)進(jìn)一個(gè)名為 MathFunctions.c 的源文件里,使得這個(gè)工程變成如下的形式:

    ./Demo2|+---?main.cc|+---?MathFunctions.cc|+---?MathFunctions.h

    這個(gè)時(shí)候,CMakeLists.txt 可以改成如下的形式:

    #?CMake?最低版本號(hào)要求 cmake_minimum_required?(VERSION?2.8)#?項(xiàng)目信息 project?(Demo2)#?指定生成目標(biāo) add_executable(Demo?main.cc?MathFunctions.cc)

    唯一的改動(dòng)只是在 add_executable 命令中增加了一個(gè) MathFunctions.cc 源文件。這樣寫(xiě)當(dāng)然沒(méi)什么問(wèn)題,但是如果源文件很多,把所有源文件的名字都加進(jìn)去將是一件煩人的工作。更省事的方法是使用 aux_source_directory 命令,該命令會(huì)查找指定目錄下的所有源文件,然后將結(jié)果存進(jìn)指定變量名。其語(yǔ)法如下:

    aux_source_directory(<dir>?<variable>)

    因此,可以修改 CMakeLists.txt 如下:

    #?CMake?最低版本號(hào)要求 cmake_minimum_required?(VERSION?2.8)#?項(xiàng)目信息 project?(Demo2)#?查找當(dāng)前目錄下的所有源文件 #?并將名稱保存到?DIR_SRCS?變量 aux_source_directory(.?DIR_SRCS)#?指定生成目標(biāo) add_executable(Demo?${DIR_SRCS})

    這樣,CMake 會(huì)將當(dāng)前目錄所有源文件的文件名賦值給變量 DIR_SRCS ,再指示變量 DIR_SRCS 中的源文件需要編譯成一個(gè)名稱為 Demo 的可執(zhí)行文件。

    ▌多個(gè)目錄,多個(gè)源文件

    本小節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo3

    現(xiàn)在進(jìn)一步將 MathFunctions.h 和 MathFunctions.cc 文件移動(dòng)到 math 目錄下。

    ./Demo3|+---?main.cc|+---?math/|+---?MathFunctions.cc|+---?MathFunctions.h

    對(duì)于這種情況,需要分別在項(xiàng)目根目錄 Demo3 和 math 目錄里各編寫(xiě)一個(gè) CMakeLists.txt 文件。為了方便,我們可以先將 math 目錄里的文件編譯成靜態(tài)庫(kù)再由 main 函數(shù)調(diào)用。根目錄中的 CMakeLists.txt :

    #?CMake?最低版本號(hào)要求 cmake_minimum_required?(VERSION?2.8)#?項(xiàng)目信息 project?(Demo3)#?查找當(dāng)前目錄下的所有源文件 #?并將名稱保存到?DIR_SRCS?變量 aux_source_directory(.?DIR_SRCS)#?添加?math?子目錄 add_subdirectory(math)#?指定生成目標(biāo)? add_executable(Demo?main.cc)#?添加鏈接庫(kù) target_link_libraries(Demo?MathFunctions)

    該文件添加了下面的內(nèi)容: 第3行,使用命令 add_subdirectory 指明本項(xiàng)目包含一個(gè)子目錄 math,這樣 math 目錄下的 CMakeLists.txt 文件和源代碼也會(huì)被處理 。第6行,使用命令 target_link_libraries 指明可執(zhí)行文件 main 需要連接一個(gè)名為 MathFunctions 的鏈接庫(kù) 。子目錄中的 CMakeLists.txt:

    #?查找當(dāng)前目錄下的所有源文件 #?并將名稱保存到?DIR_LIB_SRCS?變量 aux_source_directory(.?DIR_LIB_SRCS)#?生成鏈接庫(kù) add_library?(MathFunctions?${DIR_LIB_SRCS})

    在該文件中使用命令 add_library 將 src 目錄中的源文件編譯為靜態(tài)鏈接庫(kù)。

    ▌自定義編譯選項(xiàng)

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo4

    CMake 允許為項(xiàng)目增加編譯選項(xiàng),從而可以根據(jù)用戶的環(huán)境和需求選擇最合適的編譯方案。例如,可以將 MathFunctions 庫(kù)設(shè)為一個(gè)可選的庫(kù),如果該選項(xiàng)為 ON ,就使用該庫(kù)定義的數(shù)學(xué)函數(shù)來(lái)進(jìn)行運(yùn)算。否則就調(diào)用標(biāo)準(zhǔn)庫(kù)中的數(shù)學(xué)函數(shù)庫(kù)。

    ▌修改 CMakeLists 文件

    我們要做的第一步是在頂層的 CMakeLists.txt 文件中添加該選項(xiàng):

    #?CMake?最低版本號(hào)要求 cmake_minimum_required?(VERSION?2.8)#?項(xiàng)目信息 project?(Demo4)#?加入一個(gè)配置頭文件,用于處理?CMake?對(duì)源碼的設(shè)置 configure_file?("${PROJECT_SOURCE_DIR}/config.h.in""${PROJECT_BINARY_DIR}/config.h")#?是否使用自己的?MathFunctions?庫(kù) option?(USE_MYMATH"Use?provided?math?implementation"?ON)#?是否加入?MathFunctions?庫(kù) if?(USE_MYMATH)include_directories?("${PROJECT_SOURCE_DIR}/math")add_subdirectory?(math)??set?(EXTRA_LIBS?${EXTRA_LIBS}?MathFunctions) endif?(USE_MYMATH)#?查找當(dāng)前目錄下的所有源文件 #?并將名稱保存到?DIR_SRCS?變量 aux_source_directory(.?DIR_SRCS)#?指定生成目標(biāo) add_executable(Demo?${DIR_SRCS}) target_link_libraries?(Demo??${EXTRA_LIBS})

    其中:

  • 第7行的 configure_file 命令用于加入一個(gè)配置頭文件 config.h ,這個(gè)文件由 CMake 從 config.h.in 生成,通過(guò)這樣的機(jī)制,將可以通過(guò)預(yù)定義一些參數(shù)和變量來(lái)控制代碼的生成。

  • 第13行的 option 命令添加了一個(gè) USE_MYMATH 選項(xiàng),并且默認(rèn)值為 ON 。

  • 第17行根據(jù) USE_MYMATH 變量的值來(lái)決定是否使用我們自己編寫(xiě)的 MathFunctions 庫(kù)。

  • ▌修改 main.cc 文件

    之后修改 main.cc 文件,讓其根據(jù) USE_MYMATH 的預(yù)定義值來(lái)決定是否調(diào)用標(biāo)準(zhǔn)庫(kù)還是 MathFunctions 庫(kù):

    #include?<stdio.h> #include?<stdlib.h> #include?"config.h"#ifdef?USE_MYMATH#include?"math/MathFunctions.h" #else#include?<math.h> #endifint?main(int?argc,?char?*argv[]) {if?(argc?<?3){printf("Usage:?%s?base?exponent?\n",?argv[0]);return?1;}double?base?=?atof(argv[1]);int?exponent?=?atoi(argv[2]);#ifdef?USE_MYMATHprintf("Now?we?use?our?own?Math?library.?\n");double?result?=?power(base,?exponent); #elseprintf("Now?we?use?the?standard?library.?\n");double?result?=?pow(base,?exponent); #endifprintf("%g?^?%d?is?%g\n",?base,?exponent,?result);return?0; }

    ▌編寫(xiě) config.h.in 文件

    上面的程序值得注意的是第2行,這里引用了一個(gè) config.h 文件,這個(gè)文件預(yù)定義了 USE_MYMATH 的值。但我們并不直接編寫(xiě)這個(gè)文件,為了方便從 CMakeLists.txt 中導(dǎo)入配置,我們編寫(xiě)一個(gè) config.h.in 文件,內(nèi)容如下:

    #cmakedefine?USE_MYMATH

    這樣 CMake 會(huì)自動(dòng)根據(jù) CMakeLists 配置文件中的設(shè)置自動(dòng)生成 config.h 文件。

    ▌編譯項(xiàng)目

    現(xiàn)在編譯一下這個(gè)項(xiàng)目,為了便于交互式的選擇該變量的值,可以使用 ccmake 命令(也可以使用 cmake -i 命令,該命令會(huì)提供一個(gè)會(huì)話式的交互式配置界面):

    CMake的交互式配置界面

    CMake的交互式配置界面從中可以找到剛剛定義的 USE_MYMATH 選項(xiàng),按鍵盤(pán)的方向鍵可以在不同的選項(xiàng)窗口間跳轉(zhuǎn),按下 enter 鍵可以修改該選項(xiàng)。修改完成后可以按下 c 選項(xiàng)完成配置,之后再按 g 鍵確認(rèn)生成 Makefile 。ccmake 的其他操作可以參考窗口下方給出的指令提示。我們可以試試分別將 USE_MYMATH 設(shè)為 ON 和 OFF 得到的結(jié)果:

    ▌USE_MYMATH 為 ON

    運(yùn)行結(jié)果:

    [ehome@xman?Demo4]$?./Demo Now?we?use?our?own?MathFunctions?library.?7?^?3?=?343.00000010?^?5?=?100000.0000002?^?10?=?1024.000000

    此時(shí) config.h 的內(nèi)容為:

    #define?USE_MYMATH
    ▌USE_MYMATH 為 OFF

    運(yùn)行結(jié)果:

    [ehome@xman?Demo4]$?./Demo Now?we?use?the?standard?library.?7?^?3?=?343.00000010?^?5?=?100000.0000002?^?10?=?1024.000000

    此時(shí) config.h 的內(nèi)容為:

    /*?#undef?USE_MYMATH?*/

    ▌安裝和測(cè)試

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo5

    CMake 也可以指定安裝規(guī)則,以及添加測(cè)試。這兩個(gè)功能分別可以通過(guò)在產(chǎn)生 Makefile 后使用 make install 和 make test 來(lái)執(zhí)行。在以前的 GNU Makefile 里,你可能需要為此編寫(xiě) install 和 test 兩個(gè)偽目標(biāo)和相應(yīng)的規(guī)則,但在 CMake 里,這樣的工作同樣只需要簡(jiǎn)單的調(diào)用幾條命令。

    ▌定制安裝規(guī)則

    首先先在 math/CMakeLists.txt 文件里添加下面兩行:

    #?指定?MathFunctions?庫(kù)的安裝路徑 install?(TARGETS?MathFunctions?DESTINATION?bin) install?(FILES?MathFunctions.h?DESTINATION?include)

    指明 MathFunctions 庫(kù)的安裝路徑。之后同樣修改根目錄的 CMakeLists 文件,在末尾添加下面幾行:

    #?指定安裝路徑 install?(TARGETS?Demo?DESTINATION?bin) install?(FILES?"${PROJECT_BINARY_DIR}/config.h"DESTINATION?include)

    通過(guò)上面的定制,生成的 Demo 文件和 MathFunctions 函數(shù)庫(kù) libMathFunctions.o 文件將會(huì)被復(fù)制到 /usr/local/bin 中,而 MathFunctions.h 和生成的 config.h 文件則會(huì)被復(fù)制到 /usr/local/include 中。我們可以驗(yàn)證一下(順帶一提的是,這里的 /usr/local/ 是默認(rèn)安裝到的根目錄,可以通過(guò)修改 CMAKE_INSTALL_PREFIX 變量的值來(lái)指定這些文件應(yīng)該拷貝到哪個(gè)根目錄):

    [ehome@xman?Demo5]$?sudo?make?install [?50%]?Built?target?MathFunctions [100%]?Built?target?Demo Install?the?project... --?Install?configuration:?"" --?Installing:?/usr/local/bin/Demo --?Installing:?/usr/local/include/config.h --?Installing:?/usr/local/bin/libMathFunctions.a --?Up-to-date:?/usr/local/include/MathFunctions.h [ehome@xman?Demo5]$?ls?/usr/local/bin Demo??libMathFunctions.a [ehome@xman?Demo5]$?ls?/usr/local/include config.h??MathFunctions.h

    ▌為工程添加測(cè)試

    添加測(cè)試同樣很簡(jiǎn)單。CMake 提供了一個(gè)稱為 CTest 的測(cè)試工具。我們要做的只是在項(xiàng)目根目錄的 CMakeLists 文件中調(diào)用一系列的 add_test 命令。

    #?啟用測(cè)試 enable_testing()#?測(cè)試程序是否成功運(yùn)行 add_test?(test_run?Demo?5?2)#?測(cè)試幫助信息是否可以正常提示 add_test?(test_usage?Demo) set_tests_properties?(test_usagePROPERTIES?PASS_REGULAR_EXPRESSION?"Usage:?.*?base?exponent")#?測(cè)試?5?的平方 add_test?(test_5_2?Demo?5?2)set_tests_properties?(test_5_2PROPERTIES?PASS_REGULAR_EXPRESSION?"is?25")#?測(cè)試?10?的?5?次方 add_test?(test_10_5?Demo?10?5)set_tests_properties?(test_10_5PROPERTIES?PASS_REGULAR_EXPRESSION?"is?100000")#?測(cè)試?2?的?10?次方 add_test?(test_2_10?Demo?2?10)set_tests_properties?(test_2_10PROPERTIES?PASS_REGULAR_EXPRESSION?"is?1024")

    上面的代碼包含了四個(gè)測(cè)試。第一個(gè)測(cè)試 test_run 用來(lái)測(cè)試程序是否成功運(yùn)行并返回 0 值。剩下的三個(gè)測(cè)試分別用來(lái)測(cè)試 5 的 平方、10 的 5 次方、2 的 10 次方是否都能得到正確的結(jié)果。其中 PASS_REGULAR_EXPRESSION 用來(lái)測(cè)試輸出是否包含后面跟著的字符串。讓我們看看測(cè)試的結(jié)果:

    [ehome@xman?Demo5]$?make?test Running?tests... Test?project?/home/ehome/Documents/programming/C/power/Demo5Start?1:?test_run 1/4?Test?#1:?test_run?.........................???Passed????0.00?secStart?2:?test_5_2 2/4?Test?#2:?test_5_2?.........................???Passed????0.00?secStart?3:?test_10_5 3/4?Test?#3:?test_10_5?........................???Passed????0.00?secStart?4:?test_2_10 4/4?Test?#4:?test_2_10?........................???Passed????0.00?sec100%?tests?passed,?0?tests?failed?out?of?4Total?Test?time?(real)?=???0.01?sec

    如果要測(cè)試更多的輸入數(shù)據(jù),像上面那樣一個(gè)個(gè)寫(xiě)測(cè)試用例未免太繁瑣。這時(shí)可以通過(guò)編寫(xiě)宏來(lái)實(shí)現(xiàn):

    #?定義一個(gè)宏,用來(lái)簡(jiǎn)化測(cè)試工作 macro?(do_test?arg1?arg2?result)add_test?(test_${arg1}_${arg2}?Demo?${arg1}?${arg2})set_tests_properties?(test_${arg1}_${arg2}PROPERTIES?PASS_REGULAR_EXPRESSION?${result}) endmacro?(do_test)#?使用該宏進(jìn)行一系列的數(shù)據(jù)測(cè)試 do_test?(5?2?"is?25") do_test?(10?5?"is?100000") do_test?(2?10?"is?1024")

    關(guān)于 CTest 的更詳細(xì)的用法可以通過(guò) man 1 ctest 參考 CTest 的文檔。

    ▌支持 gdb

    讓 CMake 支持 gdb 的設(shè)置也很容易,只需要指定 Debug 模式下開(kāi)啟 -g 選項(xiàng):

    set(CMAKE_BUILD_TYPE?"Debug") set(CMAKE_CXX_FLAGS_DEBUG?"$ENV{CXXFLAGS}?-O0?-Wall?-g?-ggdb") set(CMAKE_CXX_FLAGS_RELEASE?"$ENV{CXXFLAGS}?-O3?-Wall")

    之后可以直接對(duì)生成的程序使用 gdb 來(lái)調(diào)試。

    ▌添加環(huán)境檢查

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo6

    有時(shí)候可能要對(duì)系統(tǒng)環(huán)境做點(diǎn)檢查,例如要使用一個(gè)平臺(tái)相關(guān)的特性的時(shí)候。在這個(gè)例子中,我們檢查系統(tǒng)是否自帶 pow 函數(shù)。如果帶有 pow 函數(shù),就使用它;否則使用我們定義的 power 函數(shù)。

    ▌添加 CheckFunctionExists 宏

    首先在頂層 CMakeLists 文件中添加 CheckFunctionExists.cmake 宏,并調(diào)用 check_function_exists 命令測(cè)試鏈接器是否能夠在鏈接階段找到 pow 函數(shù)。

    #?檢查系統(tǒng)是否支持?pow?函數(shù) include?(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) check_function_exists?(pow?HAVE_POW)

    將上面這段代碼放在 configure_file 命令前。

    ▌?lì)A(yù)定義相關(guān)宏變量

    接下來(lái)修改 config.h.in 文件,預(yù)定義相關(guān)的宏變量。

    //?does?the?platform?provide?pow?function? #cmakedefine?HAVE_POW

    ▌在代碼中使用宏和函數(shù)

    最后一步是修改 main.cc ,在代碼中使用宏和函數(shù):

    #ifdef?HAVE_POWprintf("Now?we?use?the?standard?library.?\n");double?result?=?pow(base,?exponent); #elseprintf("Now?we?use?our?own?Math?library.?\n");double?result?=?power(base,?exponent); #endif

    ▌添加版本號(hào)

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo7

    給項(xiàng)目添加和維護(hù)版本號(hào)是一個(gè)好習(xí)慣,這樣有利于用戶了解每個(gè)版本的維護(hù)情況,并及時(shí)了解當(dāng)前所用的版本是否過(guò)時(shí),或是否可能出現(xiàn)不兼容的情況。首先修改頂層 CMakeLists 文件,在 project 命令之后加入如下兩行:

    set?(Demo_VERSION_MAJOR?1) set?(Demo_VERSION_MINOR?0)

    分別指定當(dāng)前的項(xiàng)目的主版本號(hào)和副版本號(hào)。之后,為了在代碼中獲取版本信息,我們可以修改 config.h.in 文件,添加兩個(gè)預(yù)定義變量:

    //?the?configured?options?and?settings?for?Tutorial #define?Demo_VERSION_MAJOR?@Demo_VERSION_MAJOR@ #define?Demo_VERSION_MINOR?@Demo_VERSION_MINOR@

    這樣就可以直接在代碼中打印版本信息了:

    #include?<stdio.h> #include?<stdlib.h> #include?<math.h> #include?"config.h" #include?"math/MathFunctions.h"int?main(int?argc,?char?*argv[]) {if?(argc?<?3){//?print?version?infoprintf("%s?Version?%d.%d\n",argv[0],Demo_VERSION_MAJOR,Demo_VERSION_MINOR);printf("Usage:?%s?base?exponent?\n",?argv[0]);return?1;}double?base?=?atof(argv[1]);int?exponent?=?atoi(argv[2]);#if?defined?(HAVE_POW)printf("Now?we?use?the?standard?library.?\n");double?result?=?pow(base,?exponent); #elseprintf("Now?we?use?our?own?Math?library.?\n");double?result?=?power(base,?exponent); #endifprintf("%g?^?%d?is?%g\n",?base,?exponent,?result);return?0; }

    ▌生成安裝包

    本節(jié)對(duì)應(yīng)的源代碼所在目錄:

    https://github.com/wzpan/cmake-demo/tree/master/Demo8

    本節(jié)將學(xué)習(xí)如何配置生成各種平臺(tái)上的安裝包,包括二進(jìn)制安裝包和源碼安裝包。為了完成這個(gè)任務(wù),我們需要用到 CPack ,它同樣也是由 CMake 提供的一個(gè)工具,專門(mén)用于打包。首先在頂層的 CMakeLists.txt 文件尾部添加下面幾行:

    #?構(gòu)建一個(gè)?CPack?安裝包 include?(InstallRequiredSystemLibraries) set?(CPACK_RESOURCE_FILE_LICENSE"${CMAKE_CURRENT_SOURCE_DIR}/License.txt") set?(CPACK_PACKAGE_VERSION_MAJOR?"${Demo_VERSION_MAJOR}") set?(CPACK_PACKAGE_VERSION_MINOR?"${Demo_VERSION_MINOR}") include?(CPack)

    上面的代碼做了以下幾個(gè)工作:

  • 導(dǎo)入 InstallRequiredSystemLibraries 模塊,以便之后導(dǎo)入 CPack 模塊;

  • 設(shè)置一些 CPack 相關(guān)變量,包括版權(quán)信息和版本信息,其中版本信息用了上一節(jié)定義的版本號(hào);

  • 導(dǎo)入 CPack 模塊。

  • 接下來(lái)的工作是像往常一樣構(gòu)建工程,并執(zhí)行 cpack 命令。

    • 生成二進(jìn)制安裝包:

    cpack?-C?CPackConfig.cmake
    • 生成源碼安裝包

    cpack?-C?CPackSourceConfig.cmake

    我們可以試一下。在生成項(xiàng)目后,執(zhí)行 cpack -C CPackConfig.cmake 命令:

    [ehome@xman?Demo8]$?cpack?-C?CPackSourceConfig.cmake CPack:?Create?package?using?STGZ CPack:?Install?projects CPack:?-?Run?preinstall?target?for:?Demo8 CPack:?-?Install?project:?Demo8 CPack:?Create?package CPack:?-?package:?/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.sh?generated. CPack:?Create?package?using?TGZ CPack:?Install?projects CPack:?-?Run?preinstall?target?for:?Demo8 CPack:?-?Install?project:?Demo8 CPack:?Create?package CPack:?-?package:?/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.tar.gz?generated. CPack:?Create?package?using?TZ CPack:?Install?projects CPack:?-?Run?preinstall?target?for:?Demo8 CPack:?-?Install?project:?Demo8 CPack:?Create?package CPack:?-?package:?/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.tar.Z?generated.

    此時(shí)會(huì)在該目錄下創(chuàng)建 3 個(gè)不同格式的二進(jìn)制包文件:

    [ehome@xman?Demo8]$?ls?Demo8-* Demo8-1.0.1-Linux.sh??Demo8-1.0.1-Linux.tar.gz??Demo8-1.0.1-Linux.tar.Z

    這 3 個(gè)二進(jìn)制包文件所包含的內(nèi)容是完全相同的。我們可以執(zhí)行其中一個(gè)。此時(shí)會(huì)出現(xiàn)一個(gè)由 CPack 自動(dòng)生成的交互式安裝界面:

    [ehome@xman?Demo8]$?sh?Demo8-1.0.1-Linux.sh? Demo8?Installer?Version:?1.0.1,?Copyright?(c)?Humanity This?is?a?self-extracting?archive. The?archive?will?be?extracted?to:?/home/ehome/Documents/programming/C/power/Demo8If?you?want?to?stop?extracting,?please?press?<ctrl-C>. The?MIT?License?(MIT)Copyright?(c)?2013?Joseph?Pan(http://hahack.com)Permission?is?hereby?granted,?free?of?charge,?to?any?person?obtaining?a?copy?of this?software?and?associated?documentation?files?(the?"Software"),?to?deal?in the?Software?without?restriction,?including?without?limitation?the?rights?to use,?copy,?modify,?merge,?publish,?distribute,?sublicense,?and/or?sell?copies?of the?Software,?and?to?permit?persons?to?whom?the?Software?is?furnished?to?do?so, subject?to?the?following?conditions:The?above?copyright?notice?and?this?permission?notice?shall?be?included?in?all copies?or?substantial?portions?of?the?Software.THE?SOFTWARE?IS?PROVIDED?"AS?IS",?WITHOUT?WARRANTY?OF?ANY?KIND,?EXPRESS?OR IMPLIED,?INCLUDING?BUT?NOT?LIMITED?TO?THE?WARRANTIES?OF?MERCHANTABILITY,?FITNESS FOR?A?PARTICULAR?PURPOSE?AND?NONINFRINGEMENT.?IN?NO?EVENT?SHALL?THE?AUTHORS?OR COPYRIGHT?HOLDERS?BE?LIABLE?FOR?ANY?CLAIM,?DAMAGES?OR?OTHER?LIABILITY,?WHETHER IN?AN?ACTION?OF?CONTRACT,?TORT?OR?OTHERWISE,?ARISING?FROM,?OUT?OF?OR?IN CONNECTION?WITH?THE?SOFTWARE?OR?THE?USE?OR?OTHER?DEALINGS?IN?THE?SOFTWARE.Do?you?accept?the?license??[yN]:? y By?default?the?Demo8?will?be?installed?in:"/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux" Do?you?want?to?include?the?subdirectory?Demo8-1.0.1-Linux? Saying?no?will?install?in:?"/home/ehome/Documents/programming/C/power/Demo8"?[Yn]:? yUsing?target?directory:?/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux Extracting,?please?wait...Unpacking?finished?successfully

    完成后提示安裝到了 Demo8-1.0.1-Linux 子目錄中,我們可以進(jìn)去執(zhí)行該程序:

    [ehome@xman?Demo8]$?./Demo8-1.0.1-Linux/bin/Demo?5?2 Now?we?use?our?own?Math?library.? 5?^?2?is?25

    關(guān)于 CPack 的更詳細(xì)的用法可以通過(guò) man 1 cpack 參考 CPack 的文檔。

    ▌項(xiàng)目遷移

    CMake 可以很輕松地構(gòu)建出在適合各個(gè)平臺(tái)執(zhí)行的工程環(huán)境。而如果當(dāng)前的工程環(huán)境不是 CMake ,而是基于某個(gè)特定的平臺(tái),是否可以遷移到 CMake 呢?答案是可能的。下面針對(duì)幾個(gè)常用的平臺(tái),列出了它們對(duì)應(yīng)的遷移方案。

    ▌autotools

    • am2cmake 可以將 autotools 系的項(xiàng)目轉(zhuǎn)換到 CMake,這個(gè)工具的一個(gè)成功案例是 KDE 。

    • Alternative Automake2CMake 可以轉(zhuǎn)換使用 automake 的 KDevelop 工程項(xiàng)目。

    • Converting autoconf tests

    ▌qmake

    • qmake converter 可以轉(zhuǎn)換使用 QT 的 qmake 的工程。

    ▌Visual Studio

    • vcproj2cmake.rb 可以根據(jù) Visual Studio 的工程文件(后綴名是 .vcproj 或 .vcxproj)生成 CMakeLists.txt 文件。

    • vcproj2cmake.ps1 vcproj2cmake 的 PowerShell 版本。

    • folders4cmake 根據(jù) Visual Studio 項(xiàng)目文件生成相應(yīng)的 “source_group” 信息,這些信息可以很方便的在 CMake 腳本中使用。支持 Visual Studio 9/10 工程文件。

    ▌CMakeLists.txt 自動(dòng)推導(dǎo)

    • gencmake 根據(jù)現(xiàn)有文件推導(dǎo) CMakeLists.txt 文件。

    • CMakeListGenerator 應(yīng)用一套文件和目錄分析創(chuàng)建出完整的 CMakeLists.txt 文件。僅支持 Win32 平臺(tái)。

    ▌相關(guān)鏈接

  • 官方主頁(yè):https://github.com/wzpan/cmake-demo/tree/master/Demo1

  • 官方文檔:http://www.cmake.org/cmake/help/cmake2.4docs.html

  • 官方教程:http://www.cmake.org/cmake/help/cmake_tutorial.html

  • ▌?lì)愃乒ぞ?/h2>
    • SCons:Eric S. Raymond、Timothee Besset、Zed A. Shaw 等大神力薦的項(xiàng)目架構(gòu)工具。和 CMake 的最大區(qū)別是使用 Python 作為執(zhí)行腳本。

    ▌溫馨提示

    由于微信公眾號(hào)近期改變了推送規(guī)則,如果您想經(jīng)常看到我們的文章,可以在每次閱讀后,在頁(yè)面下方點(diǎn)一個(gè)「贊」或「在看」,這樣每次推送的文章才會(huì)第一時(shí)間出現(xiàn)在您的訂閱列表里。

    版權(quán)聲明:本文來(lái)源網(wǎng)絡(luò),免費(fèi)傳達(dá)知識(shí),版權(quán)歸原作者所有。如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系我進(jìn)行刪除。


    推薦閱讀:

    專輯|Linux文章匯總

    專輯|程序人生

    專輯|C語(yǔ)言

    我的知識(shí)小密圈

    關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤(pán)鏈接。

    歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~

    總結(jié)

    以上是生活随笔為你收集整理的分享一篇很不错的CMake入门文章,值得收藏细读!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。