步驟 5:安裝與測試

練習 1 - 安裝規則

通常,僅僅建置可執行檔是不夠的,它也應該是可安裝的。使用 CMake,我們可以利用 install() 命令來指定安裝規則。在 CMake 中支援本機建置的安裝通常就像指定安裝位置以及要安裝的目標和檔案一樣簡單。

目標

安裝 Tutorial 可執行檔和 MathFunctions 函式庫。

有用的材料

要編輯的檔案

  • MathFunctions/CMakeLists.txt

  • CMakeLists.txt

開始

起始程式碼在 Step5 目錄中提供。在這個練習中,完成 TODO 1TODO 4

首先,更新 MathFunctions/CMakeLists.txt,將 MathFunctionstutorial_compiler_flags 函式庫安裝到 lib 目錄。在同一個檔案中,指定將 MathFunctions.h 安裝到 include 目錄所需的安裝規則。

然後,更新頂層的 CMakeLists.txt,將 Tutorial 可執行檔安裝到 bin 目錄。最後,任何標頭檔都應該安裝到 include 目錄。請記住,TutorialConfig.h 位於 PROJECT_BINARY_DIR 中。

建置與執行

建立一個名為 Step5_build 的新目錄。執行 cmake 可執行檔或 cmake-gui 來設定專案,然後使用您選擇的建置工具進行建置。

然後,從命令列使用 cmake 命令的 --install 選項(3.15 版本中引入,較舊版本的 CMake 必須使用 make install)執行安裝步驟。此步驟將安裝適當的標頭檔、函式庫和可執行檔。例如

cmake --install .

對於多組態工具,別忘了使用 --config 引數來指定組態。

cmake --install . --config Release

如果使用 IDE,只需建置 INSTALL 目標即可。您可以像下面這樣從命令列建置相同的安裝目標

cmake --build . --target install --config Debug

CMake 變數 CMAKE_INSTALL_PREFIX 用於判斷檔案將安裝到的根目錄。如果使用 cmake --install 命令,可以透過 --prefix 引數覆寫安裝首碼。例如

cmake --install . --prefix "/home/myuser/installdir"

導覽至安裝目錄並驗證已安裝的 Tutorial 是否可執行。

解決方案

我們專案的安裝規則相當簡單

  • 對於 MathFunctions,我們希望將函式庫和標頭檔分別安裝到 libinclude 目錄。

  • 對於 Tutorial 可執行檔,我們希望將可執行檔和設定的標頭檔分別安裝到 bininclude 目錄。

因此,在 MathFunctions/CMakeLists.txt 的末尾我們新增

TODO 1:點擊以顯示/隱藏答案
TODO 1:MathFunctions/CMakeLists.txt
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
  list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib)

以及

TODO 2:點擊以顯示/隱藏答案
TODO 2:MathFunctions/CMakeLists.txt
install(FILES MathFunctions.h DESTINATION include)

Tutorial 可執行檔和設定的標頭檔的安裝規則是相似的。在頂層 CMakeLists.txt 的末尾我們新增

TODO 3,4:點擊以顯示/隱藏答案
CMakeLists.txt
install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  DESTINATION include
  )

這就是建立教學基本本機安裝所需的一切。

練習 2 - 測試支援

CTest 提供了一種輕鬆管理專案測試的方式。可以透過 add_test() 命令新增測試。儘管本教學中沒有明確涵蓋,但 CTest 與其他測試框架(例如 GoogleTest)之間有很大的相容性。

目標

使用 CTest 為我們的可執行檔建立單元測試。

有用的材料

要編輯的檔案

  • CMakeLists.txt

開始

起始原始碼在 Step5 目錄中提供。在這個練習中,完成 TODO 5TODO 9

首先,我們需要啟用測試。接下來,開始使用 add_test() 將測試新增到我們的專案。我們將逐步新增 3 個簡單的測試,然後您可以視需要新增額外的測試。

建置與執行

導覽至建置目錄並重建應用程式。然後,執行 ctest 可執行檔:ctest -Nctest -VV。對於多組態產生器(例如 Visual Studio),必須使用 -C <模式> 旗標指定組態類型。例如,若要在偵錯模式下執行測試,請從建置目錄(而非偵錯子目錄!)使用 ctest -C Debug -VV。發行模式將從相同位置執行,但使用 -C Release。或者,從 IDE 建置 RUN_TESTS 目標。

解決方案

讓我們測試我們的應用程式。在頂層 CMakeLists.txt 檔案的末尾,我們首先需要使用 enable_testing() 命令啟用測試。

TODO 5:點擊以顯示/隱藏答案
TODO 5:CMakeLists.txt
enable_testing()

啟用測試後,我們將加入一些基本測試,以驗證應用程式是否正常運作。首先,我們使用 add_test() 建立一個測試,該測試會執行 Tutorial 可執行檔,並傳入參數 25。對於此測試,我們不會檢查可執行檔計算出的答案。此測試將驗證應用程式是否執行、是否未發生區段錯誤或其他崩潰,並且具有零傳回值。這是 CTest 測試的基本形式。

待辦事項 6:點擊以顯示/隱藏答案
待辦事項 6:CMakeLists.txt
add_test(NAME Runs COMMAND Tutorial 25)

接下來,讓我們使用 PASS_REGULAR_EXPRESSION 測試屬性來驗證測試的輸出是否包含特定的字串。在此案例中,驗證當提供不正確的引數數量時,是否會印出使用訊息。

待辦事項 7:點擊以顯示/隱藏答案
待辦事項 7:CMakeLists.txt
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
  )

我們要加入的下一個測試,將驗證計算出的值是否確實是平方根。

待辦事項 8:點擊以顯示/隱藏答案
待辦事項 8:CMakeLists.txt
add_test(NAME StandardUse COMMAND Tutorial 4)
set_tests_properties(StandardUse
  PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
  )

僅靠這一個測試,不足以讓我們確信它適用於所有傳入的值。我們應該加入更多測試來驗證這一點。為了方便加入更多測試,我們建立一個名為 do_test 的函式,該函式會執行應用程式並驗證對於給定的輸入,計算出的平方根是否正確。對於每次調用 do_test,都會在專案中加入另一個測試,其名稱、輸入和預期結果都是基於傳入的引數。

待辦事項 9:點擊以顯示/隱藏答案
待辦事項 9:CMakeLists.txt
function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endfunction()

# do a bunch of result based tests
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")