CMake: テスト対象プロジェクトのGitサブモジュールを自動初期化する「CTEST_GIT_INIT_SUBMODULES」


具体的な動作

  1. サブモジュールの初期化
    CTEST_GIT_INIT_SUBMODULES が ON に設定されている場合、CMake はテスト実行前にプロジェクトディレクトリ内のすべての Git サブモジュールを初期化します。これは、git submodule update --init --recursive コマンドを実行することで実行されます。
  2. 再帰的初期化
    デフォルトでは、CTEST_GIT_INIT_SUBMODULES は再帰的に動作し、プロジェクトディレクトリ内のすべてのサブディレクトリを探索し、その中に含まれるサブモジュールも初期化します。この動作を無効にするには、CTEST_GIT_INIT_SUBMODULES_RECURSEOFF に設定する必要があります。
  3. 特定のサブモジュールの初期化
    特定のサブモジュールのみを初期化したい場合は、CTEST_GIT_INIT_SUBMODULES_REMOTE 変数を使用して、初期化するサブモジュールのリモート URL を指定できます。この変数はカンマ区切りのリストとして設定できます。
  4. エラー処理
    サブモジュールの初期化が失敗した場合、CMake はエラーメッセージを出力し、テスト実行を中止します。


cmake_minimum_required(VERSION 3.10)

project(MyProject)

git_submodule("submodule1" "https://github.com/user/submodule1.git")
git_submodule("submodule2" "https://github.com/user/submodule2.git")

set(CTEST_GIT_INIT_SUBMODULES ON)

add_test(MyTest1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest1)
add_test(MyTest2 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest2)

上記の例では、CTEST_GIT_INIT_SUBMODULESON に設定されているため、submodule1submodule2 という 2 つのサブモジュールがテスト実行前に初期化されます。

CTEST_GIT_INIT_SUBMODULES を使用する利点

  • テスト環境の再現性を向上させる
  • テスト実行前に手動でサブモジュールを初期化する必要がない
  • テストに必要なすべての依存関係が確実に満たされる
  • サブモジュールに依存するテストのみで CTEST_GIT_INIT_SUBMODULES を使用する
  • サブモジュールの更新ポリシーを理解する
  • サブモジュールのリモート URL が正しく設定されていることを確認する


cmake_minimum_required(VERSION 3.10)

project(MyProject)

git_submodule("submodule1" "https://github.com/user/submodule1.git")
git_submodule("submodule2" "https://github.com/user/submodule2.git")

set(CTEST_GIT_INIT_SUBMODULES ON)

add_test(MyTest1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest1)
add_test(MyTest2 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest2)

説明

  • この例では、CTEST_GIT_INIT_SUBMODULESON に設定されているため、submodule1submodule2 という 2 つのサブモジュールがテスト実行前に初期化されます。

例 2: 特定のサブモジュールのみを初期化する

cmake_minimum_required(VERSION 3.10)

project(MyProject)

git_submodule("submodule1" "https://github.com/user/submodule1.git")
git_submodule("submodule2" "https://github.com/user/submodule2.git")

set(CTEST_GIT_INIT_SUBMODULES OFF)
set(CTEST_GIT_INIT_SUBMODULES_REMOTE "https://github.com/user/submodule1.git")

add_test(MyTest1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest1)
add_test(MyTest2 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest2)

説明

  • CTEST_GIT_INIT_SUBMODULES_REMOTEhttps://github.com/user/submodule1.git という URL を設定することで、submodule1 のみを初期化するように指定しています。
  • この例では、CTEST_GIT_INIT_SUBMODULESOFF に設定されているため、デフォルトではサブモジュールは初期化されません。

例 3: 再帰的初期化を無効にする

cmake_minimum_required(VERSION 3.10)

project(MyProject)

git_submodule("submodule1" "https://github.com/user/submodule1.git")
git_submodule("submodule2" "https://github.com/user/submodule2.git")

set(CTEST_GIT_INIT_SUBMODULES ON)
set(CTEST_GIT_INIT_SUBMODULES_RECURSE OFF)

add_test(MyTest1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest1)
add_test(MyTest2 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/MyTest2)
  • CTEST_GIT_INIT_SUBMODULES_RECURSEOFF に設定することで、再帰的初期化を無効にし、submodule1 内のサブモジュールは初期化されません。
  • この例では、CTEST_GIT_INIT_SUBMODULESON に設定されているため、submodule1 がテスト実行前に初期化されます。


手動でサブモジュールを初期化する

git submodule update --init --recursive

利点

  • サブモジュールの初期化をより細かく制御できる
  • 最もシンプルな方法

欠点

  • スクリプト化が必要な場合は、複雑になる可能性がある
  • テストを実行する前に毎回手動で初期化する必要がある

カスタム CMake ターゲットを作成する

add_custom_target(init_submodules COMMAND git submodule update --init --recursive)

add_dependencies(MyTest1 init_submodules)
add_dependencies(MyTest2 init_submodules)

利点

  • 依存関係を明確に定義できる
  • テストを実行する前に自動的にサブモジュールを初期化できる

欠点

  • コードが冗長になる可能性がある
  • CMake の知識が必要

CTest の ctest_submodule_update コマンドを使用する

ctest --command ctest_submodule_update

利点

  • サブモジュールの初期化とテスト実行を 1 つのコマンドで実行できる
  • CTest を使用している場合に簡単

欠点

  • コマンドラインインターフェースでのみ使用可能
  • CTest をインストールする必要がある

サブモジュールの自動更新を有効にする

[submodule "submodule1"]
autoUpdate = true

利点

  • 手動で初期化する必要がない
  • サブモジュールが常に最新の状態に保たれる

欠点

  • 予期しない更新によるテストの失敗が発生する可能性がある
  • サブモジュールの更新時にネットワーク接続が必要
  • 開発者のスキルセット
  • テスト環境の再現性
  • サブモジュールの更新頻度