FetchContent
與 Git連結: Day 15 - Colab
記得在 Day 14 的範例中, 我們是先將套件下載到本地端, 在 local build 並安裝之後, 才將該套件拉進我們的 CMake 專案, 有點麻煩
今天會介紹 FetchContent
的第二種用法, 讓我們可以省略手動下載的步驟, 直接用 FetchContent_Declare(Git)
指定 tag 並下載 Github 的專案!
今天會延續 Day 14 的範例, 搭配 Day 12 介紹過的 Link Seams 技巧, 把使用 fmt
的功能單獨拆成一個 static library, 並在測試時將他 mock 掉, 也可以去今天的 Colab 看比較清楚
在開始之前, 先來引入 googletest
吧
FetchContent
與 googletest
除了 googletest
以外, 我們將 Day 14 的 fmt
也改由 FetchContent
加入
include(FetchContent)
set(FETCHCONTENT_QUIET OFF)
FetchContent_Declare(fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_REMOTE_NAME origin
GIT_TAG 10.1.1
GIT_SHALLOW TRUE
)
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest.git GIT_REMOTE_NAME origin
GIT_TAG v1.14.0
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(fmt googletest)
我們在下載 (FetchContent_Declare()
) 前, 先把 FETCHCONTENT_QUIET
設為 OFF
, 就可以看到在引入 fmt
和 googletest
時做了哪些事
-- Populating fmt
-- Configuring done
-- Generating done
-- Build files have been written to: /content/cmake-example/build/_deps/fmt-subbuild
[ 11%] Creating directories for 'fmt-populate'
[ 22%] Performing download step (git clone) for 'fmt-populate'
Cloning into 'fmt-src'...
HEAD is now at f5e5435 Update version
[ 33%] Performing update step for 'fmt-populate'
[ 44%] No patch step for 'fmt-populate'
[ 55%] No configure step for 'fmt-populate'
[ 66%] No build step for 'fmt-populate'
[ 77%] No install step for 'fmt-populate'
[ 88%] No test step for 'fmt-populate'
[100%] Completed 'fmt-populate'
[100%] Built target fmt-populate
-- Version: 10.1.0
-- Populating googletest
-- Configuring done
-- Generating done
-- Build files have been written to: /content/cmake-example/build/_deps/googletest-subbuild
[ 11%] Performing update step for 'googletest-populate'
[ 22%] No patch step for 'googletest-populate'
[ 33%] No configure step for 'googletest-populate'
[ 44%] No build step for 'googletest-populate'
[ 55%] No install step for 'googletest-populate'
[ 66%] No test step for 'googletest-populate'
[ 77%] Completed 'googletest-populate'
[100%] Built target googletest-populate
可以看到兩個套件都成功產出 build scripts 了
Day 14 已經提過如何 link fmt
, 這裡我們需要知道 googletest
提供了哪些 targets 讓我們 link
首先, 去看看 官方文件, 可以在 Create and run a binary 的地方看到有提供範例
add_executable(
hello_test
hello_test.cc
)
target_link_libraries(
hello_test
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
如上所示, 我們需要 link GTest::gtest_main
我們先建立一個測試並寫死 PASS()
直接通過src/test/test_main.cpp
#include <gtest/gtest.h>
namespace {
TEST(UsageTest, CanUseGoogleTest) {
SUCCEED();
}
} // anonymous namespace
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
然後 build 該 test targetsrc/test/CMakeLists.txt
add_executable(TestMain
test_main.cpp
)
target_link_libraries(TestMain PRIVATE
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(TestMain)
然後執行測試 ctest --test-dir build
, 可以看到我們的測試出現在 terminal 了🎉🎉🎉
Internal ctest changing into directory: /content/cmake-example/build
Test project /content/cmake-example/build
Start 1: UsageTest.CanUseGoogleTest
1/1 Test #1: UsageTest.CanUseGoogleTest ....... Passed 0.00 sec
關於如何寫測試或是如何使用 GoogleTest 並不在本系列的介紹範圍
有興趣的話請參考 GoogleTest 官方文件
add_test()
如果不想用 googletest
的話, 也可以用 CMake 自己提供的 add_test()
來增加 test cases, 用法如下
add_test(NAME <name> COMMAND <command> [<arg>...]
[CONFIGURATIONS <config>...]
[WORKING_DIRECTORY <dir>]
[COMMAND_EXPAND_LISTS])
NAME
COMMAND
CMAKE_CURRENT_BINARY_DIR
) 底下CONFIGURATIONS
ctest -C <build-config>
使用, 可以指定 build typeWORKING_DIRECTORY
COMMAND
執行的路徑COMMAND_EXPAND_LISTS
COMMAND
args
展開所以我們可以將上面的測試改成這樣
add_executable(TestMain
test_main.cpp
)
target_link_libraries(TestMain PRIVATE
GTest::gtest_main
)
add_test(NAME TestMain COMMAND TestMain)
執行結果會和用 googletest 一樣
了解了引入 libraries 的方法之後, 還需要了解日後該如何更新套件版本
除此之外, 如果我們想要將 library export 給其他人使用, 也需要設定好版本, 這些將在下一篇介紹