次の方法で共有


CMake スタイル ガイド

次のいずれかであるすべての CMake スクリプトが必要です。

  • ディレクトリ内 scripts/ 、または
  • ポート内vcpkg-*

は、このドキュメントに記載されているガイドラインに従う必要があります。 既存のスクリプトは、これらのガイドラインにまだ従っていない可能性があります。これらのガイドラインに従って古いスクリプトを引き続き更新することが期待されます。

これらのガイドラインは、スクリプトに安定性を生み出すことを目的としています。 前方互換性と下位互換性の両方を容易にすることを願っています。

ガイドライン

  • アウトパラメーターを除き、関数パラメーターや参照ではなく、常に使用 cmake_parse_arguments() します ${ARG<N>}

    • これは必ずしも "スクリプト ローカル ヘルパー関数" に従う必要はありません

      • この場合、位置指定パラメーターは (使用${ARG<N>}するのではなく) 関数宣言に配置し、ローカル ルール (つまり) に従って名前を付ける必要があります。 snake_case
      • 例外: 省略可能な位置指定パラメーターは、チェック後に名前を付set(argument_name "${ARG<N>}")けるARGC必要があります。
    • 出力パラメーターは、関数の最初のパラメーターである必要があります。 例:

      function(format out_var)
        cmake_parse_arguments(PARSE_ARGV 1 "arg" ...)
        # ... set(buffer "output")
        set("${out_var}" "${buffer}" PARENT_SCOPE)
      endfunction()
      
  • 解析されていない引数や未使用の引数はありません。 常にチェックしますARGNarg_UNPARSED_ARGUMENTSFATAL_ERROR 可能な場合は、 WARNING 下位互換性のために必要に応じて〘。

  • すべて cmake_parse_arguments 使用 PARSE_ARGVする必要があります。

  • すべてのforeachループで 、IN LISTSまたは RANGE. IN ITEMS

  • 変数 ${ARGV} であり ${ARGN} 、ユーザーに役立つメッセージを除き、参照されません。

    • (つまり、 message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}"))
  • マクロや最上位のコードではなく、常に関数を使用します。

    • 例外: "script-local helper macros"。 小さなマクロを定義すると便利な場合があります。 これは控えめに行う必要があり、関数を優先する必要があります。
    • 例外: vcpkg.cmake's find_package.
  • スクリプト ツリー内のスクリプトでは、通常の操作の一環として監視可能な変更が必要になることは想定されません。

    • 違反の例: vcpkg_acquire_msys() MSYS プロジェクトが古いパッケージを削除するため、時間の経過と伴う更新が必要なパッケージとバージョンがハードコーディングされています。
    • 例外例: vcpkg_from_sourceforge() ミラーの一覧があり、メインテナントが必要ですが、呼び出し元に対する観測可能な動作の影響はありません。
  • 引用符の規則: CMake には、引用符で囲まれていない ()、引用符foo("BAR") ()、角かっこfoo([[BAR]]) (foo(BAR)) の 3 種類の引数があります。 正しく見積もるために、次の規則に従います。

    • 引数に変数拡張 ${...}が含まれている場合は、引用符で囲む必要があります。

      • 例外: 1 つの変数が複数の引数として関数に渡される場合の "splat" 変数拡張。 この場合、引数は次のようになります ${foo}

        vcpkg_list(SET working_directory)
        if(DEFINED "arg_WORKING_DIRECTORY")
          vcpkg_list(SET working_directory WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}")
        endif()
        # calls do_the_thing() if NOT DEFINED arg_WORKING_DIRECTORY,
        # else calls do_the_thing(WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}")
        do_the_thing(${working_directory})
        
    • それ以外の場合、引数に引用符で囲まれた引数ではない\\\"\$エスケープ シーケンスが含まれている場合は、その引数を引用符で囲む必要があります。

      • たとえば、 "foo\nbar" 引用符で囲む必要があります。
    • それ以外の場合、引数に 、a"、または a $が含まれている\場合は、その引数を角かっこで囲む必要があります。

      • 例:

        set(x [[foo\bar]])
        set(y [=[foo([[bar\baz]])]=])
        
    • それ以外の場合、引数に英数字または _英数字以外の文字が含まれている場合は、その引数を引用符で囲む必要があります。

    • それ以外の場合は、引数を引用符で囲む必要があります。

    • 例外: 型<variable|string>の引数は常にif()引用符で囲む必要があります。

      • 比較演算子に対する両方の引数 - EQUALSTREQUAL、、 VERSION_LESSなど。

      • and に対する最初の MATCHES 引数 IN_LIST

      • 例:

        if("${FOO}" STREQUAL "BAR") # ...
        if("${BAZ}" EQUAL "0") # ...
        if("FOO" IN_LIST list_variable) # ...
        if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
        
      • 単一の式と、受け取 <variable|string>らない他の種類の述語の場合は、通常の規則を使用します。

  • 単純な out-parameters を除き、"ポインター" パラメーターまたは "in-out" パラメーター (ユーザーが内容ではなく変数名を渡す) はありません。

  • 変数は空とは見なされません。 変数がローカルで使用されることを意図している場合は、文字列変数の場合とvcpkg_list(SET foo)リスト変数の場合は、明示的に空set(foo "")に初期化する必要があります。

  • set(var) は使用しないでください。 変数の設定を解除し、set(var "")空の文字列に設定しvcpkg_list(SET var)、空のリストに設定するために使用unset(var)します。 注: 空の文字列と空のリストは同じ値です。これは結果の違いではなく、表記上の違いです

  • API 境界を越えて親スコープから継承されることが予想されるすべての変数 (つまり、ファイルローカル関数ではない) を文書化する必要があります。 Triplet ファイルメンションされるすべての変数が文書化されていると見なされます。

  • Out パラメーターは、設定 PARENT_SCOPE されているだけであり、読み取られたことはありません。 関数スコープを介してパラメーターを転送するヘルパー z_vcpkg_forward_output_variable() も参照してください。

  • CACHE 変数は、厳密に結合された関数間で内部的に共有されるグローバル変数と、1 つの関数内の内部状態に対してのみ使用され、作業が重複しないようにします。 これらは非常に控えめに使用する必要があり、プレフィックスを Z_VCPKG_ 使用して、他のコードで定義されるローカル変数との衝突を回避する必要があります。

    • 例:
      • vcpkg_cmake_configure's Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_vars's Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()s は、〘または vcpkg-port-config.cmakeports.cmake

  • foreach(RANGE)'の引数は常に自然な数値である必要があり<start>、常に次の値以下<stop>である必要があります。

    • これは、次のような方法でチェックする必要があります。

      if("${start}" LESS_EQUAL "${end}")
        foreach(RANGE "${start}" "${end}")
          ...
        endforeach()
      endif()
      
  • ポート ベースのすべてのスクリプトは、複数回含まれるのを避けるために使用 include_guard(GLOBAL) する必要があります。

必要な CMake バージョン

  • を除くvcpkg.cmakeすべての CMake スクリプトは、次の CMake に存在する CMake のports.cmakeバージョンをcmake_minimum_required想定できます。
    • これはcmake_minimum_required、すべてのヘルパー CMakeLists.txt ファイルと同様cmake_minimum_requiredvcpkgTools.xml、新しいバージョンの CMake が追加されるたびにバンプする必要があります。
  • vcpkg.cmake CMake のバージョンを 3.7.2 に戻す必要があります。
    • 特定の関数とオプションでは、より大きな CMake バージョンが想定される場合があります。その場合は、必要な CMake バージョンでその関数またはオプションをコメントしてください。

既存の関数の変更

  • 非内部関数の引数を削除しないでください。何もする必要がなくなった場合は、通常どおりに受け取り、使用時に警告します。
  • 新しい必須引数を追加しないでください。

変数に名前を付ける

  • cmake_parse_arguments: プレフィックスを > に設定します。 "arg"

  • ローカル変数の名前は次のとおりです。 snake_case

  • 内部グローバル変数名の先頭 Z_VCPKG_に .

  • 外部の実験用グローバル変数名の先頭 X_VCPKG_に .

  • 内部関数の先頭に z_vcpkg_

    • 1 つの関数 (つまり、ヘルパー関数) の内部にある関数には[z_]<func>_<name><func>、ヘルパー関数の名前、ヘルパー関数<name>の名前を指定します。
      • z_は、ヘルパー関数z_z_foo_barに名前を付けない場合<func>z_は、前面に追加する必要があります。
  • パブリック グローバル変数の名前 VCPKG_を指定します。