플랫폼으로 마이그레이션

문제 신고 소스 보기

Bazel은 다중 아키텍처와 크로스 컴파일된 빌드를 위한 모델링 플랫폼도구 모음을 정교하게 지원합니다.

이 페이지에는 이 지원의 상태가 요약되어 있습니다.

참고 항목

상태

C++

C++ 규칙은 --incompatible_enable_cc_toolchain_resolution가 설정된 경우 플랫폼을 사용하여 도구 모음을 선택합니다.

즉, 다음을 사용하여 C++ 프로젝트를 구성할 수 있습니다.

bazel build //:my_cpp_project --platforms=//:myplatform

다음과 같습니다.

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

이는 Bazel 7.0에서 기본적으로 사용 설정됩니다 (#7260).

플랫폼에서 C++ 프로젝트를 테스트하려면 프로젝트 이전C++ 도구 모음 구성을 참조하세요.

Java

자바 규칙은 플랫폼을 사용하여 도구 모음을 선택합니다.

이는 기존 플래그 --java_toolchain, --host_java_toolchain, --javabase, --host_javabase를 대체합니다.

자세한 내용은 자바 및 Bazel을 참고하세요.

Android

Android 규칙은 --incompatible_enable_android_toolchain_resolution가 설정된 경우 플랫폼을 사용하여 도구 모음을 선택합니다.

즉, 다음을 사용하여 Android 프로젝트를 구성할 수 있습니다.

bazel build //:my_android_project --android_platforms=//:my_android_platform

--android_crosstool_top, --android_cpu, --fat_apk_cpu와 같은 기존 플래그를 사용하는 대신

이는 Bazel 7.0에서 기본적으로 사용 설정됩니다 (#16285).

플랫폼에서 Android 프로젝트를 테스트하려면 프로젝트 이전을 참고하세요.

사과

Apple 규칙은 플랫폼을 지원하지 않으며 아직 지원 예정이 아닙니다.

Apple 규칙과 순수 C++를 함께 사용하여 플랫폼 매핑을 사용하여 빌드하는 경우와 같이 Apple 빌드에서 플랫폼 API를 계속 사용할 수 있습니다.

다른 언어

  • Go 규칙은 플랫폼을 완벽하게 지원합니다.
  • Rust 규칙은 플랫폼을 완벽하게 지원합니다.

언어 규칙 집합을 소유하는 경우 규칙 집합 이전에서 지원 기능을 확인하세요.

배경

소프트웨어 프로젝트가 다양한 아키텍처를 타겟팅하고 크로스 컴파일하는 방법을 표준화하기 위해 플랫폼도구 모음이 도입되었습니다.

이는 언어 유지관리자가 이미 호환되지 않는 임시적인 방식으로 이 작업을 수행하고 있다는 관찰에서 영감을 얻었습니다. 예를 들어 C++ 규칙은 --cpu--crosstool_top를 사용하여 타겟 CPU와 도구 모음을 선언했습니다. 둘 중 어느 것도 '플랫폼'을 올바르게 모델링하지 않습니다. 이로 인해 어색하고 잘못된 빌드가 생성되었습니다.

Java, Android 및 기타 언어는 비슷한 목적을 위해 자체 플래그를 발전시켰으며 어느 것도 서로 상호 운용되지 않았습니다. 이로 인해 언어 간 빌드가 혼란스럽고 복잡했습니다.

Bazel은 대규모 다국어 다중 플랫폼 프로젝트에 적합합니다. 따라서 명확한 표준 API를 포함하여 이러한 개념에 관한 좀 더 원칙적인 지원이 필요합니다.

마이그레이션의 필요성

새 API로 업그레이드하려면 두 가지 작업이 필요합니다. 즉, API를 출시하고 이 API를 사용하기 위해 규칙 로직을 업그레이드해야 합니다.

첫 번째 작업은 완료되었지만 두 번째 작업은 계속 진행 중입니다. 이는 언어별 플랫폼과 도구 모음이 정의되도록 하고, 언어 로직은 --crosstool_top와 같은 이전 플래그 대신 새 API를 통해 도구 모음을 읽으며, config_setting가 이전 플래그 대신 새 API에서 선택합니다.

이 작업은 간단하지만 각 언어마다 별개의 작업이 필요하며, 프로젝트 소유자가 향후 변경사항을 테스트하도록 공정한 경고가 필요합니다.

이것이 바로 이전이 진행 중인 이유입니다.

목표

모든 프로젝트가 다음 형식으로 빌드되면 이 마이그레이션이 완료됩니다.

bazel build //:myproject --platforms=//:myplatform

이는 다음을 의미합니다.

  1. 프로젝트 규칙이 //:myplatform에 적합한 도구 모음을 선택합니다.
  2. 프로젝트의 종속 항목이 //:myplatform에 적합한 도구 모음을 선택합니다.
  3. //:myplatformCPU, OS 및 기타 일반적인 언어 독립적 속성의 공통 선언을 참조합니다.
  4. 모든 관련 select()//:myplatform와 올바르게 일치합니다.
  5. //:myplatform는 명확하고 액세스 가능한 위치에 정의됩니다. 즉, 프로젝트의 저장소(플랫폼이 프로젝트별로 고유한 경우) 또는 모든 소비하는 모든 프로젝트에서 찾을 수 있는 일반적인 위치에서 정의됩니다.

--cpu, --crosstool_top, --fat_apk_cpu와 같은 이전 플래그는 지원 중단되고 안전해지는 즉시 삭제됩니다.

궁극적으로 이는 아키텍처를 구성하는 유일한 방법이 될 것입니다.

프로젝트 마이그레이션

플랫폼을 지원하는 언어로 빌드하는 경우 빌드는 이미 다음과 같은 호출로 작동해야 합니다.

bazel build //:myproject --platforms=//:myplatform

정확한 세부정보는 상태 및 사용 언어 설명서를 참고하세요.

언어에 플랫폼 지원을 사용 설정하는 플래그가 필요한 경우 해당 플래그도 설정해야 합니다. 자세한 내용은 상태를 참조하세요.

프로젝트를 빌드하려면 다음을 확인해야 합니다.

  1. //:myplatform이(가) 있어야 합니다. 프로젝트마다 다른 머신을 대상으로 하므로 플랫폼을 정의하는 것은 일반적으로 프로젝트 소유자의 책임입니다. 기본 플랫폼을 참조하세요.

  2. 사용하려는 도구 모음이 있어야 합니다. 주식 도구 모음을 사용하는 경우 언어 소유자는 도구 등록 방법에 관한 지침을 포함해야 합니다. 자체 커스텀 도구 모음을 작성하는 경우 MODULE.bazel 파일 또는 --extra_toolchains를 사용하여 도구 모음을 register해야 합니다.

  3. select()구성 전환이 제대로 확인되어야 합니다. select()Transitions를 참고하세요.

  4. 빌드에 플랫폼을 지원하는 언어와 지원하지 않는 언어가 혼합되어 있는 경우 기존 언어가 새 API에서 작동할 수 있도록 플랫폼 매핑이 필요할 수 있습니다. 자세한 내용은 플랫폼 매핑을 참고하세요.

문제가 계속되면 지원팀에 문의하세요.

기본 플랫폼

프로젝트 소유자는 빌드하려는 아키텍처를 설명하는 명시적인 플랫폼을 정의해야 합니다. 그런 다음 --platforms로 트리거됩니다.

--platforms가 설정되지 않은 경우 Bazel은 로컬 빌드 머신을 나타내는 platform을 기본값으로 설정합니다. 이는 @local_config_platform//:host에서 자동 생성되므로 명시적으로 정의할 필요가 없습니다. 로컬 머신의 OSCPU@platforms에 선언된 constraint_value로 매핑합니다.

select()

프로젝트는 constraint_value 대상에서 select()할 수 있지만 전체 플랫폼에서는 불가능합니다. 이는 select()에서 가능한 한 다양한 머신을 지원하기 위해 의도된 것입니다. ARM 특정 소스가 있는 라이브러리는 더 구체적인 이유가 없는 한 모든 ARM 지원 머신을 지원해야 합니다.

하나 이상의 constraint_value를 선택하려면 다음을 사용합니다.

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

이는 일반적으로 --cpu에서 선택하는 것과 같습니다.

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

자세한 내용은 여기를 참조하세요.

--cpu, --crosstool_top 등의 select--platforms를 이해하지 못합니다. 프로젝트를 플랫폼으로 이전할 때 constraint_values로 변환하거나 플랫폼 매핑을 사용하여 이전 중에 두 스타일을 모두 지원해야 합니다.

화면전환

Starlark 전환은 빌드 그래프의 일부분으로 플래그를 변경합니다. 프로젝트에서 --cpu, --crossstool_top 또는 다른 레거시 플래그를 설정하는 전환을 사용하는 경우 --platforms를 읽는 규칙에 이러한 변경사항이 표시되지 않습니다.

프로젝트를 플랫폼으로 이전할 때는 return { "//command_line_option:cpu": "arm" }와 같은 변경사항을 return { "//command_line_option:platforms": "//:my_arm_platform" }로 변환하거나 플랫폼 매핑을 사용하여 이전 중에 두 스타일을 모두 지원해야 합니다.

규칙 세트 이전

규칙 세트를 소유하고 있고 플랫폼을 지원하려면 다음을 실행해야 합니다.

  1. 규칙 로직이 도구 모음 API를 사용하여 도구 모음을 확인하도록 합니다. 도구 모음 API (ctx.toolchains)를 참고하세요.

  2. 선택사항: 이전 테스트 중에 규칙 로직이 새 API 또는 이전 플래그(예: --crosstool_top)를 통해 도구 모음을 대체하도록 --incompatible_enable_platforms_for_my_language 플래그를 정의합니다.

  3. 플랫폼 구성요소를 구성하는 관련 속성을 정의합니다. 공통 플랫폼 속성을 참고하세요.

  4. 표준 도구 모음을 정의하고 규칙의 등록 안내에 따라 사용자가 액세스할 수 있도록 합니다 (세부정보).

  5. select()구성 전환이 플랫폼을 지원하는지 확인합니다. 이것이 가장 큰 과제입니다. 특히 다국어 프로젝트에서는 어렵습니다(모든 언어가 --platforms를 읽을 수 없으면 실패할 수 있음).

플랫폼을 지원하지 않는 규칙과 함께 사용해야 하는 경우 플랫폼 매핑을 사용하여 이 간극을 메워야 할 수 있습니다.

일반적인 플랫폼 속성

OSCPU와 같은 일반적인 언어 간 플랫폼 속성은 @platforms에서 선언해야 합니다. 이를 통해 공유, 표준화, 언어 간 호환성을 장려할 수 있습니다.

규칙에 고유한 속성은 규칙의 저장소에서 선언해야 합니다. 이를 통해 규칙이 담당하는 특정 개념에 대한 명확한 소유권을 유지할 수 있습니다.

규칙에서 커스텀 용도 OS나 CPU를 사용하는 경우 @platforms 대신 규칙의 저장소에 선언해야 합니다.

플랫폼 매핑

플랫폼 매핑은 플랫폼 인식 로직을 동일한 빌드에서 기존 로직과 혼합할 수 있는 임시 API입니다. 이 도구는 다양한 마이그레이션 기간과의 비호환성을 해결하기 위한 목적으로만 사용되며

플랫폼 매핑은 platform()와 상응하는 기존 플래그 집합의 매핑 또는 그 반대로의 매핑입니다. 예를 들면 다음과 같습니다.

platforms:
  # Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
  //platforms:ios
    --ios_multi_cpus=x86_64
    --apple_platform_type=ios

flags:
  # Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --ios_multi_cpus=x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --apple_platform_type=macos
    //platforms:macos

Bazel은 이를 사용하여 플랫폼 기반 및 레거시 모든 설정이 전환을 통해 빌드 전반에 걸쳐 일관되게 적용되도록 보장합니다.

기본적으로 Bazel은 작업공간 루트의 platform_mappings 파일에서 매핑을 읽습니다. --platform_mappings=//:my_custom_mapping를 설정할 수도 있습니다.

자세한 내용은 플랫폼 매핑 설계를 참고하세요.

API 검토

platformconstraint_value 타겟의 모음입니다.

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value는 머신 속성입니다. 동일한 '종류'의 값은 공통 constraint_setting 아래에 그룹화됩니다.

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchainStarlark 규칙입니다. 속성은 언어 도구 (예: compiler = "//mytoolchain:custom_gcc")를 선언합니다. 제공자는 이 정보를 이러한 도구로 빌드해야 하는 규칙에 이 정보를 전달합니다.

도구 모음은 타겟팅할 수 있는 머신(target_compatible_with = ["@platforms//os:linux"])과 도구를 실행할 수 있는 머신(exec_compatible_with = ["@platforms//os:mac"])의 constraint_value를 선언합니다.

$ bazel build //:myproject --platforms=//:myplatform를 빌드할 때 Bazel은 빌드 머신에서 실행할 수 있는 도구 모음과 //:myplatform용 빌드 바이너리를 자동으로 선택합니다. 이를 도구 모음 해결이라고 합니다.

사용 가능한 도구 모음 집합은 MODULE.bazel 파일에서 register_toolchains로 또는 명령줄에서 --extra_toolchains로 등록할 수 있습니다.

자세한 내용은 여기를 참고하세요.

질문

마이그레이션 타임라인에 대한 일반적인 지원 및 질문은 bazel-discuss 또는 해당 규칙 소유자에게 문의하세요.

플랫폼/도구 모음 API의 설계와 발전에 대한 논의는 bazel-dev에 문의하세요.

참고 항목