다음을 통해 공유


CMake 스타일 가이드

다음과 같은 모든 CMake 스크립트가 예상됩니다.

  • scripts/ 디렉터리 또는
  • 포트에서 vcpkg-*

는 이 문서에 설명된 지침을 따라야 합니다. 기존 스크립트는 아직 이러한 지침을 따르지 않을 수 있습니다. 이 지침에 따라 이전 스크립트를 계속 업데이트할 것으로 예상됩니다.

이러한 지침은 스크립트의 안정성을 만들기 위한 것입니다. 앞으로 또는 이전 버전과의 호환성을 더 쉽게 만들 수 있기를 바랍니다.

지침

  • out 매개 변수를 제외하고 함수 매개 변수나 참조 ${ARG<N>}대신 항상 사용합니다cmake_parse_arguments().

    • "스크립트-로컬 도우미 함수"를 반드시 따를 필요는 없습니다.

      • 이 경우 위치 매개 변수는 함수 선언(사용 ${ARG<N>}대신)에 배치해야 하며 로컬 규칙(예: snake_case)에 따라 이름을 지정해야 합니다.
      • 예외: 선택 사항인 위치 매개 변수는 확인 ARGC후 를 통해 set(argument_name "${ARG<N>}")이름을 지정해야 합니다.
    • 아웃 매개 변수는 함수의 첫 번째 매개 변수여야 합니다. 예시:

      function(format out_var)
        cmake_parse_arguments(PARSE_ARGV 1 "arg" ...)
        # ... set(buffer "output")
        set("${out_var}" "${buffer}" PARENT_SCOPE)
      endfunction()
      
  • 구문 분석되지 않은 인수나 사용되지 않은 인수는 없습니다. 항상 확인 ARGN 하거나 arg_UNPARSED_ARGUMENTS. FATAL_ERROR 가능 WARNING 하면 이전 버전과의 호환성을 위해 필요한 경우

  • 모두 cmake_parse_arguments 을 사용해야 PARSE_ARGV합니다.

  • 모든 foreach 루프는 또는 IN ITEMSRANGE.를 사용해야 IN LISTS합니다.

  • 사용자에게 유용한 메시지를 제외하고 변수 ${ARGV} 이며 ${ARGN} 참조되지 않습니다.

    • (예: message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}"))
  • 매크로나 최상위 코드가 아닌 함수를 항상 사용합니다.

    • 예외: "스크립트 로컬 도우미 매크로". 작은 매크로를 정의하는 것이 도움이 되는 경우도 있습니다. 이 작업은 아쉽게 수행해야 하며 함수를 선호해야 합니다.
    • 예외: vcpkg.cmake's find_package.
  • 스크립트 트리의 스크립트는 정상 작업의 일부로 관찰 가능한 변경이 필요하지 않아야 합니다.

    • 위반 예: vcpkg_acquire_msys() MSYS 프로젝트가 이전 패키지를 삭제하여 시간이 지남에 따라 업데이트해야 하는 하드 코딩된 패키지 및 버전이 있습니다.
    • 예외 예: vcpkg_from_sourceforge() 유지 관리가 필요하지만 호출자에게 관찰 가능한 동작 영향을 주지 않는 미러 목록이 있습니다.
  • 따옴표로 묶는 규칙: CMake에는 따옴표가 지정되지 않은(), 따옴표foo("BAR")(foo(BAR)) 및 대괄호로 묶인(foo([[BAR]]))의 세 가지 인수가 있습니다. 다음 규칙을 따라 올바르게 인용합니다.

    • 인수에 변수 확장 ${...}이 포함된 경우 인수를 따옴표로 묶어야 합니다.

      • 예외: 한 변수가 함수에 여러 인수로 전달될 때 "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() 인수는 항상 따옴표로 묶어야 합니다.

      • 비교 연산EQUAL자( , , STREQUALVERSION_LESS등)에 대한 두 인수

      • 다음의 첫 번째 인수입니다.MATCHESIN_LIST

      • 예시:

        if("${FOO}" STREQUAL "BAR") # ...
        if("${BAZ}" EQUAL "0") # ...
        if("FOO" IN_LIST list_variable) # ...
        if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
        
      • 단일 식 및 사용하지 <variable|string>않는 다른 유형의 조건자의 경우 일반 규칙을 사용합니다.

  • 간단한 아웃 매개 변수를 제외하고 "포인터" 또는 "인아웃" 매개 변수(사용자가 내용이 아닌 변수 이름을 전달하는 경우)는 없습니다.

  • 변수는 비어 있는 것으로 간주되지 않습니다. 변수를 로컬로 사용하려는 경우 문자열 변수인 경우 및 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 변수는 강력한 결합 함수 간에 내부적으로 공유되는 전역 변수 및 중복 작업을 방지하기 위해 단일 함수 내의 내부 상태에만 사용됩니다. 이러한 변수는 매우 드물게 사용해야 하며 접두사를 사용하여 Z_VCPKG_ 다른 코드에서 정의할 지역 변수와 충돌하지 않도록 해야 합니다.

    • 예:
      • vcpkg_cmake_configure's Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_vars's Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()s는 in 또는 vcpkg-port-config.cmake.에서 ports.cmake 만 허용됩니다.

  • foreach(RANGE)'의 인수는 항상 자연수여야 하며 <start> 항상 1보다 작거나 같<stop>아야 합니다.

    • 다음과 같은 항목을 통해 확인해야 합니다.

      if("${start}" LESS_EQUAL "${end}")
        foreach(RANGE "${start}" "${end}")
          ...
        endforeach()
      endif()
      
  • 모든 포트 기반 스크립트는 여러 번 포함되지 않도록 하기 위해 사용해야 include_guard(GLOBAL) 합니다.

필요한 CMake 버전

  • 를 제외한 vcpkg.cmake모든 CMake 스크립트는 에 있는 cmake_minimum_required ports.cmakeCMake 버전을 가정할 수 있습니다.
    • 모든 도우미 CMakeLists.txt 파일에서와 마찬가지로 CMake의 새 버전이 추가vcpkgTools.xmlcmake_minimum_required 때마다 충돌 cmake_minimum_required 해야 합니다.
  • vcpkg.cmake 는 일반적으로 CMake 버전을 3.7.2로 다시 가정해야 합니다.
    • 특정 함수 및 옵션은 더 큰 CMake 버전을 가정할 수 있습니다. 이 경우 필요한 CMake 버전으로 해당 함수 또는 옵션을 주석으로 처리해야 합니다.

기존 함수 변경

  • 비 내부 함수에서 인수를 제거하지 마세요. 그들은 더 이상 아무것도하지 않아야하는 경우, 그냥 정상적으로 그들을 가지고 사용에 경고합니다.
  • 새 필수 인수를 추가하지 마세요.

변수 명명

  • cmake_parse_arguments: 접두사를 로 설정 "arg"

  • 지역 변수의 이름은 로 지정됩니다. snake_case

  • 내부 전역 변수 이름은 접두사로 Z_VCPKG_입니다.

  • 외부 실험적 전역 변수 이름은 접두사로 X_VCPKG_입니다.

  • 내부 함수는 접두사로 z_vcpkg_

    • 단일 함수(즉, 도우미 함수) 내부 함수의 이름은 도우미인 함수의 이름 [z_]<func>_<name><func> 이며 <name> 도우미 함수가 수행하는 작업입니다.
      • z_ 이 없는 경우 <func> z_앞에 추가해야 하지만 도우미 함수 z_z_foo_bar의 이름을 지정하지 않아야 합니다.
  • 공용 전역 변수의 이름은 VCPKG_다음과 같습니다.