플랫폼

문제 신고 소스 보기 1박 · 7.4 에서 자세한 내용을 확인하실 수 있습니다. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel은 다양한 하드웨어, 운영체제, 시스템 구성 등 다양한 버전의 빌드 도구를 사용하여 사용할 수 있습니다 이러한 복잡성을 관리하는 데 도움이 되도록 Bazel에는 제약조건플랫폼 개념이 있습니다. 제약 조건은 CPU 아키텍처, GPU의 유무, 시스템에 설치된 컴파일러의 버전과 같이 빌드 또는 프로덕션 환경이 다를 수 있는 측정기준입니다. 플랫폼은 이러한 제약 조건에 대한 이름이 지정된 선택사항 모음으로, 일부 환경에서 사용할 수 있는 특정 리소스를 나타냅니다.

환경을 플랫폼으로 모델링하면 Bazel에서 빌드 작업에 적절한 도구 모음을 자동으로 선택하는 데 도움이 됩니다. 플랫폼을 config_setting 구성 가능한 속성을 쓰는 규칙이 있습니다.

Bazel은 플랫폼이 지원할 수 있는 세 가지 역할을 인식합니다.

  • 호스트 - Bazel 자체가 실행되는 플랫폼입니다.
  • 실행 - 빌드 도구가 빌드 작업을 실행하는 플랫폼입니다. 중간 및 최종 출력을 생성합니다.
  • 타겟: 최종 출력이 저장되고 실행되는 플랫폼입니다.

Bazel은 플랫폼과 관련하여 다음과 같은 빌드 시나리오를 지원합니다.

  • 단일 플랫폼 빌드(기본값) - 호스트, 실행, 타겟 플랫폼이 동일합니다. 예를 들어 Intel x64 CPU에서 실행되는 Ubuntu에서 Linux 실행 파일을 빌드하는 경우

  • 크로스 컴파일 빌드: 호스트 및 실행 플랫폼은 동일하지만 대상 플랫폼은 다릅니다. 예를 들어 MacBook Pro에서 실행되는 macOS에서 iOS 앱을 빌드하는 경우

  • 멀티플랫폼 빌드: 호스트, 실행, 대상 플랫폼이 모두 다릅니다.

제약조건 및 플랫폼 정의

플랫폼에 가능한 선택 공간은 BUILD 파일 내의 constraint_settingconstraint_value 규칙을 사용하여 정의됩니다. constraint_setting는 새 측정기준을 만들고, constraint_value는 지정된 측정기준에 새 값을 만듭니다. 함께하면 enum과 가능한 값을 효과적으로 정의합니다. 예를 들어 BUILD 파일의 스니펫이 시스템의 glibc 버전에 관한 제약 조건을 도입함 두 개의 값을 가질 수 있습니다.

constraint_setting(name = "glibc_version")

constraint_value(
    name = "glibc_2_25",
    constraint_setting = ":glibc_version",
)

constraint_value(
    name = "glibc_2_26",
    constraint_setting = ":glibc_version",
)

제약 조건과 그 값은 워크스페이스의 여러 패키지에서 정의될 수 있습니다. 라벨로 참조되며 일반적인 공개 상태 제어의 적용을 받습니다. 가시성이 허용하는 경우 자체 값을 정의하여 기존 제약 조건 설정을 확장할 수 있습니다.

platform 규칙은 특정 제약 조건 값을 선택할 수 있는 새 플랫폼을 도입합니다. 이 linux_x86라는 플랫폼을 만들고 x86_64 아키텍처에서 Linux 운영체제를 실행하는 glibc 버전 2.25 Bazel의 기본 제공 제약 조건에 대한 자세한 내용은 아래를 참조하세요.

platform(
    name = "linux_x86",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
        ":glibc_2_25",
    ],
)

일반적으로 유용한 제약 조건 및 플랫폼

생태계의 일관성을 유지하기 위해 Bazel팀은 가장 많이 사용되는 CPU 아키텍처 및 운영체제에 대한 제약 조건 정의 있습니다 이것들은 모두 https://github.com/bazelbuild/platforms.

Bazel에는 다음과 같은 특수 플랫폼 정의가 포함됩니다. @local_config_platform//:host 자동 감지된 호스트 플랫폼 값입니다. Bazel이 실행 중인 시스템의 자동 감지된 플랫폼을 나타냅니다.

빌드의 플랫폼 지정

다음을 사용하여 빌드의 호스트 및 대상 플랫폼을 지정할 수 있습니다. 명령줄 플래그:

  • --host_platform - 기본값은 @bazel_tools//platforms:host_platform입니다.
  • --platforms - 기본값은 @bazel_tools//platforms:target_platform입니다.

호환되지 않는 타겟 건너뛰기

특정 타겟 플랫폼용으로 빌드할 때는 해당 플랫폼에서 작동하지 않는 타겟은 건너뛰는 것이 좋습니다. 예: Windows 기기 드라이버가 컴퓨터에 빌드될 때 많은 컴파일러 오류를 //...가 있는 Linux 머신 사용 target_compatible_with 속성을 사용하여 코드에 있는 대상 플랫폼 제약 조건을 Bazel에 알립니다.

이 속성을 가장 간단하게 사용하면 타겟을 단일 플랫폼으로 제한할 수 있습니다. 이 타겟은 제약이 있습니다 다음 예는 win_driver_lib.cc를 64비트로 제한합니다. 창.

cc_library(
    name = "win_driver_lib",
    srcs = ["win_driver_lib.cc"],
    target_compatible_with = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
    ],
)

:win_driver_lib는 64비트 Windows로 빌드하는 경우에만 호환되며 그 밖의 경우에는 호환되지 않습니다. 비호환성은 전이적입니다. 호환되지 않는 대상에 전이 종속되는 모든 대상은 자체적으로 호환되지 않는 것으로 간주됩니다.

언제 대상을 건너뛰나요?

타겟이 호환되지 않는 것으로 간주되면 건너뛰어지며 타겟 패턴 확장의 일부로 빌드에 포함됩니다. 예를 들어 다음 두 호출은 대상 패턴 확장에서 발견된 호환되지 않는 대상을 건너뜁니다.

$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all

test_suite의 비호환 테스트도 마찬가지로 test_suite가 명령줄에서 --expand_test_suites로 지정된 경우 건너뜁니다. 즉, 명령줄의 test_suite 타겟은 :all...처럼 동작합니다. --noexpand_test_suites를 사용하면 확장이 방지되고 호환되지 않는 테스트가 있는 test_suite 타겟도 호환되지 않게 됩니다.

명령줄에서 호환되지 않는 타겟을 명시적으로 지정하면 오류 메시지가 표시되고 빌드가 실패합니다.

$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully

더 표현력 있는 제약 조건

제약 조건을 더 유연하게 표현하려면 어떤 플랫폼도 충족하지 않는 @platforms//:incompatible constraint_value를 사용하세요.

@platforms//:incompatible와 함께 select()를 사용하여 더 복잡한 제한사항을 표현합니다. 대상 예를 들어 이를 사용하여 기본 OR 로직을 구현합니다. 다음은 라이브러리를 표시합니다. macOS 및 Linux와 호환되지만 다른 플랫폼은 없습니다.

cc_library(
    name = "unixish_lib",
    srcs = ["unixish_lib.cc"],
    target_compatible_with = select({
        "@platforms//os:osx": [],
        "@platforms//os:linux": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

위의 내용은 다음과 같이 해석될 수 있습니다.

  1. macOS를 타겟팅하는 경우 타겟에 제약조건이 없습니다.
  2. Linux를 대상으로 하는 경우, 타겟에는 제약 조건이 없습니다.
  3. 그 외의 경우 타겟에 @platforms//:incompatible 제약 조건이 있습니다. 왜냐하면 @platforms//:incompatible이(가) 플랫폼에 속하지 않으므로 타겟은 다음과 같습니다. 호환되지 않는 것으로 간주됩니다.

제약 조건을 더 쉽게 읽을 수 있도록 다음을 사용합니다. skylibselects.with_or()

역호환성도 비슷한 방식으로 표현할 수 있습니다. 다음 예를 참고하세요. ARM을 제외한 모든 항목과 호환되는 라이브러리를 설명합니다.

cc_library(
    name = "non_arm_lib",
    srcs = ["non_arm_lib.cc"],
    target_compatible_with = select({
        "@platforms//cpu:arm": ["@platforms//:incompatible"],
        "//conditions:default": [],
    ],
)

bazel cquery를 사용하여 호환되지 않는 타겟 감지

IncompatiblePlatformProvider bazel cqueryStarlark 출력 형식을 사용하면 호환되지 않는 타겟을 호환되는 타겟에서 분리합니다

이를 사용하여 호환되지 않는 타겟을 필터링할 수 있습니다. 아래 예는 호환되는 타겟의 라벨만 출력합니다. 호환되지 않는 타겟은 인쇄되지 않습니다.

$ cat example.cquery

def format(target):
  if "IncompatiblePlatformProvider" not in providers(target):
    return target.label
  return ""


$ bazel cquery //... --output=starlark --starlark:file=example.cquery

알려진 문제

호환되지 않는 대상 공개 상태 무시 제한사항을 따릅니다.