구성

문제 신고 소스 보기 1박 · 7.2 · 7.1 · 7.0 · 6.5 · 6.4

이 페이지에서는 Starlark 구성의 이점과 기본 사용법을 다룹니다. 프로젝트 빌드 방식을 맞춤설정하는 Bazel API 여기에는 Kubernetes와 빌드 설정과 예제를 제공합니다.

이를 통해 다음과 같은 작업이 가능합니다.

  • 이제 프로젝트에 맞춤 플래그를 정의할 수 있어 --define 드림
  • 쓰기 deps를 구성하기 위한 전환 상위 요소와는 다른 구성을 (예: --compilation_mode=opt 또는 --cpu=arm)
  • 규칙 기본 설정 품질 개선 (예: //my:android_app 사용)

그 외 모두 .bzl 파일에서 가져온 것입니다 (Bazel 릴리스는 필요하지 않음). 자세한 내용은 bazelbuild/examples 저장소: 예시

사용자 정의 빌드 설정

빌드 설정은 구성 확인할 수 있습니다 구성을 키/값 맵이라고 생각하면 됩니다. --cpu=ppc 설정 그리고 --copt="-DFoo"는 다음과 같은 구성을 생성합니다. {cpu: ppc, copt: "-DFoo"}입니다. 각 항목은 빌드 설정입니다.

cpucopt와 같은 기존 플래그는 기본 설정입니다. 키가 정의되고 값은 네이티브 bazel 자바 코드 내에 설정됩니다. Bazel 사용자는 명령줄을 통해서만 이를 읽고 쓸 수 있습니다. 기타 API를 기본적으로 제공합니다 네이티브 플래그 및 API 변경 사용하려면 bazel 출시가 필요합니다. 사용자 정의 빌드 설정은 .bzl 파일에 정의되어 있으므로 bazel 출시가 필요하지 않음 레지스터 변경사항). 또한 명령줄을 통해 설정할 수도 있습니다. (flags로 지정된 경우 아래 자세한 내용 참고) 사용자 정의 전환을 통해 설정됩니다.

빌드 설정 정의

엔드 투 엔드 예시

build_setting rule() 매개변수

빌드 설정은 다른 규칙과 마찬가지로 Starlark rule() 함수의 build_setting 속성을 사용하여 준비하세요.

# example/buildsettings/build_settings.bzl
string_flag = rule(
    implementation = _impl,
    build_setting = config.string(flag = True)
)

build_setting 속성은 빌드 설정으로 이동합니다 유형은 다음과 같은 기본 Starlark 유형 세트로 제한됩니다. boolstring. config 모듈 보기 자세한 내용은 문서를 참조하세요. 입력이 더 복잡할 경우 수행할 수 있습니다. 자세한 내용은 아래를 참조하세요.

config 모듈의 함수는 선택적 불리언 매개변수인 flag를 사용합니다. 기본적으로 false로 설정됩니다. flag를 true로 설정하면 빌드 설정이 사용자가 명령줄에서, 규칙 작성자가 내부적으로 설정할 수 있습니다. 기본 값 및 전환을 통해 이루어집니다. 모든 설정이 사용자가 설정할 수 있어야 하는 것은 아닙니다. 예를 들어 규칙에 따라 테스트 규칙 내에서 사용 설정하고자 하는 디버그 모드가 있습니다. 사용자가 무차별적으로 사용 설정할 수 있는 기능을 기능을 테스트하지 않는 다른 규칙 내부에서만 사용할 수 있습니다.

ctx.build_setting_value 사용

모든 규칙과 마찬가지로 빌드 설정 규칙에는 구현 함수가 있습니다. 빌드 설정의 기본 Starlark 유형 값은 ctx.build_setting_value 메서드를 사용하여 지도 가장자리에 패딩을 추가할 수 있습니다. 이 방법은 빌드 설정 규칙의 ctx 객체 이러한 구현은 메서드는 빌드 설정 값을 직접 전달하거나 유형 검사 또는 좀 더 복잡한 구조체 생성과 같이 작동합니다. 이 enum 유형의 빌드 설정을 구현해야 합니다.

# example/buildsettings/build_settings.bzl
TemperatureProvider = provider(fields = ['type'])

temperatures = ["HOT", "LUKEWARM", "ICED"]

def _impl(ctx):
    raw_temperature = ctx.build_setting_value
    if raw_temperature not in temperatures:
        fail(str(ctx.label) + " build setting allowed to take values {"
             + ", ".join(temperatures) + "} but was set to unallowed value "
             + raw_temperature)
    return TemperatureProvider(type = raw_temperature)

temperature = rule(
    implementation = _impl,
    build_setting = config.string(flag = True)
)

다중 세트 문자열 플래그 정의

문자열 설정에는 추가 allow_multiple 매개변수가 있습니다. 이 매개변수를 사용하면 플래그를 명령줄 또는 bazelrcs에서 여러 번 설정할 수 있습니다. 기본값 값은 여전히 문자열 유형 속성으로 설정됩니다.

# example/buildsettings/build_settings.bzl
allow_multiple_flag = rule(
    implementation = _impl,
    build_setting = config.string(flag = True, allow_multiple = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "allow_multiple_flag")
allow_multiple_flag(
    name = "roasts",
    build_setting_default = "medium"
)

플래그의 각 설정은 단일 값으로 취급됩니다.

$ bazel build //my/target --//example:roasts=blonde \
    --//example:roasts=medium,dark

위는 {"//example:roasts": ["blonde", "medium,dark"]}로 파싱되고 ctx.build_setting_value["blonde", "medium,dark"] 목록을 반환합니다.

빌드 설정 인스턴스화

build_setting 매개변수로 정의된 규칙에는 암시적 필수 항목이 있습니다. build_setting_default 속성 이 속성은 build_setting 매개변수에 의해 선언됩니다.

# example/buildsettings/build_settings.bzl
FlavorProvider = provider(fields = ['type'])

def _impl(ctx):
    return FlavorProvider(type = ctx.build_setting_value)

flavor = rule(
    implementation = _impl,
    build_setting = config.string(flag = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
    name = "favorite_flavor",
    build_setting_default = "APPLE"
)

사전 정의된 설정

엔드 투 엔드 예시

Skylib 라이브러리에는 필수 작업 없이 인스턴스화할 수 있는 사전 정의된 설정 집합이 포함되어 있습니다. 커스텀 Starlark를 작성합니다.

예를 들어 제한된 문자열 값 집합을 허용하는 설정을 정의하는 방법은 다음과 같습니다.

# example/BUILD
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
string_flag(
    name = "myflag",
    values = ["a", "b", "c"],
    build_setting_default = "a",
)

전체 목록은 다음을 참조하세요. 일반적인 빌드 설정 규칙

빌드 설정 사용

빌드 설정에 따라

타겟이 구성 정보의 일부를 읽으려는 경우 일반 속성 종속 항목을 통해 빌드 설정에 직접 종속됩니다.

# example/rules.bzl
load("//example/buildsettings:build_settings.bzl", "FlavorProvider")
def _rule_impl(ctx):
    if ctx.attr.flavor[FlavorProvider].type == "ORANGE":
        ...

drink_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "flavor": attr.label()
    }
)
# example/BUILD
load("//example:rules.bzl", "drink_rule")
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
    name = "favorite_flavor",
    build_setting_default = "APPLE"
)
drink_rule(
    name = "my_drink",
    flavor = ":favorite_flavor",
)

언어에서 모든 규칙이 정상적으로 작동하는 표준화된 빌드 설정 집합을 영향을 받을 수 있습니다 fragments의 기본 개념은 더 이상 Starlark 구성 세계에서 하드코딩된 객체로 존재하지만 공통된 암시적 속성 세트를 사용하는 것입니다. 예를 들면 다음과 같습니다.

# kotlin/rules.bzl
_KOTLIN_CONFIG = {
    "_compiler": attr.label(default = "//kotlin/config:compiler-flag"),
    "_mode": attr.label(default = "//kotlin/config:mode-flag"),
    ...
}

...

kotlin_library = rule(
    implementation = _rule_impl,
    attrs = dicts.add({
        "library-attr": attr.string()
    }, _KOTLIN_CONFIG)
)

kotlin_binary = rule(
    implementation = _binary_impl,
    attrs = dicts.add({
        "binary-attr": attr.label()
    }, _KOTLIN_CONFIG)

명령줄에서 빌드 설정 사용

대부분의 네이티브 플래그와 마찬가지로 명령줄을 사용하여 빌드 설정을 지정할 수 있습니다. 플래그로 표시된 항목을 참고하세요. 빌드 설정 이름은 name=value 구문을 사용하는 전체 대상 경로입니다.

$ bazel build //my/target --//example:string_flag=some-value # allowed
$ bazel build //my/target --//example:string_flag some-value # not allowed

다음과 같은 특수한 불리언 구문이 지원됩니다.

$ bazel build //my/target --//example:boolean_flag
$ bazel build //my/target --no//example:boolean_flag

빌드 설정 별칭 사용

빌드 설정 대상 경로의 별칭을 설정하여 가독성을 높일 수 있습니다. gcloud 명령어입니다 별칭은 네이티브 플래그와 유사하게 작동하며 더블 대시 옵션 구문입니다.

--flag_alias=ALIAS_NAME=TARGET_PATH을 추가하여 별칭 설정 .bazelrc . 예를 들어 별칭을 coffee로 설정하려면 다음을 실행합니다.

# .bazelrc
build --flag_alias=coffee=//experimental/user/starlark_configurations/basic_build_setting:coffee-temp

권장사항: 별칭을 여러 번 설정하면 가장 최근의 그중 하나가 우선 적용됩니다 의도하지 않은 파싱 결과를 방지하려면 고유한 별칭 이름을 사용하세요.

별칭을 사용하려면 빌드 설정 대상 경로 대신 별칭을 입력합니다. 다음은 사용자의 .bazelrc에 설정된 위 coffee의 예입니다.

$ bazel build //my/target --coffee=ICED

다음을 대신해서 사용합니다.

$ bazel build //my/target --//experimental/user/starlark_configurations/basic_build_setting:coffee-temp=ICED

권장사항: 명령줄에서 별칭을 설정할 수 있지만 .bazelrc를 사용하면 명령줄의 복잡성이 줄어듭니다.

라벨 유형 빌드 설정

엔드 투 엔드 예시

다른 빌드 설정과 달리 라벨 유형 설정은 build_setting 규칙 매개변수 대신 bazel에는 두 가지 기본 제공 규칙이 있습니다. label_flaglabel_setting. 이러한 규칙은 타겟의 이름을 지정합니다. label_flag 및 전환으로 label_setting를 읽고 쓸 수 있고 label_flag를 설정할 수 있습니다. 다른 build_setting 규칙처럼 사용자가 변경할 수 있습니다. 이 둘의 유일한 차이점은 정의할 수 없습니다

라벨 입력 설정은 지연 바운드 기능을 대체하게 될 것입니다. 기본값입니다. 지연 바인딩 기본 속성은 최종 값은 구성의 영향을 받을 수 있습니다. Starlark에서는 이것이 configuration_field API에 액세스할 수 있습니다.

# example/rules.bzl
MyProvider = provider(fields = ["my_field"])

def _dep_impl(ctx):
    return MyProvider(my_field = "yeehaw")

dep_rule = rule(
    implementation = _dep_impl
)

def _parent_impl(ctx):
    if ctx.attr.my_field_provider[MyProvider].my_field == "cowabunga":
        ...

parent_rule = rule(
    implementation = _parent_impl,
    attrs = { "my_field_provider": attr.label() }
)

# example/BUILD
load("//example:rules.bzl", "dep_rule", "parent_rule")

dep_rule(name = "dep")

parent_rule(name = "parent", my_field_provider = ":my_field_provider")

label_flag(
    name = "my_field_provider",
    build_setting_default = ":dep"
)

빌드 설정 및 select()

엔드 투 엔드 예시

사용자는 select() 빌드 설정 대상을flag_values config_setting입니다. 구성과 일치하는 값은 그런 다음 String는 일치를 위해 빌드 설정의 유형으로 파싱됩니다.

config_setting(
    name = "my_config",
    flag_values = {
        "//example:favorite_flavor": "MANGO"
    }
)

사용자 정의 전환

구성 전환 구성된 한 타겟에서 빌드 그래프에서 확인할 수 있습니다.

이를 설정하는 규칙은 특수 속성을 포함해야 합니다.

  "_allowlist_function_transition": attr.label(
      default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
  )

전환을 추가하면 장면의 크기를 매우 쉽게 폭발적으로 증가시킬 수 있습니다. 빌드 그래프에 사용합니다. 이렇게 하면 이 규칙의 대상을 만듭니다. 위 코드 블록의 기본값은 모든 것을 허용 목록에 추가합니다 규칙을 사용할 사용자를 제한하려면 이 속성이 자체 맞춤 허용 목록을 가리키도록 설정할 수 있습니다. 조언이나 지원이 필요한 경우 bazel-discuss@googlegroups.com으로 문의하세요. 전환이 빌드 성능에 미치는 영향을 이해하는 데 도움이 됩니다.

정의

전환은 규칙 간의 구성 변경을 정의합니다. 예를 들어 예를 들어 '상위 CPU가 아닌 다른 CPU에 대한 종속 항목을 컴파일'하는 것입니다. 인코더-디코더 아키텍처를 있습니다.

공식적으로 전환은 입력 구성에서 하나 이상의 구성으로의 함수입니다. 출력 구성을 생성합니다 대부분의 전환은 1:1입니다(예: '입력 재정의 --cpu=ppc로 구성 1:2+ 전환도 가능하지만 특별한 제한이 적용됩니다.

Starlark에서 전환은 규칙과 매우 흡사하게 정의되며 transition() 함수 구현 함수가 있습니다.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {"//example:favorite_flavor" : "MINT"}

hot_chocolate_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

transition() 함수는 구현 함수인 읽을 빌드 설정(inputs)과 쓸 빌드 설정 세트 (outputs). 구현 함수에는 settingsattr입니다. settings은(는) 선언된 모든 설정의 {String:Object} 사전입니다. inputs 매개변수에서 transition()로 설정합니다.

attr는 첨부됩니다. 아웃바운드 에지 전환이 있으면 이 값이 속성은 모두 선택된 post-select() 해상도입니다. 첨부 시 들어오는 가장자리 전환인 경우 attr는 선택기를 사용하여 값을 확인하는 모든 속성을 포함합니다. 만약 --foo의 수신 에지 전환은 bar 속성을 읽은 후 --foo에서 선택하여 bar 속성을 설정하면 전환 시 잘못된 bar 값을 읽기 위해 수신 에지 전환

구현 함수는 사전 (또는 사용하는 경우 여러 출력 구성으로 전환) 적용할 새 빌드 설정 값의 범위를 지정합니다. 반환된 사전 키 세트는 outputs에 전달된 빌드 설정 세트를 정확하게 포함합니다. 매개변수 값으로 사용됩니다. 빌드 설정이 는 전환 과정에서 실제로 변경되지 않습니다. 원래 값은 반환된 사전에서 명시적으로 전달됩니다.

1:2+ 전환 정의

엔드 투 엔드 예시

발신 가장자리 전환은 단일 입력을 매핑할 수 있습니다. 2개 이상의 출력 구성에 적용할 수 있습니다 이 유형은 인코더-디코더 아키텍처를 기반으로 합니다.

1:2+ 전환은 구현 함수입니다.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return [
        {"//example:favorite_flavor" : "LATTE"},
        {"//example:favorite_flavor" : "MOCHA"},
    ]

coffee_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

또한 규칙 구현 함수에서 사용할 수 있는 커스텀 키를 설정할 수 있습니다. 개별 종속 항목을 읽습니다.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {
        "Apple deps": {"//command_line_option:cpu": "ppc"},
        "Linux deps": {"//command_line_option:cpu": "x86"},
    }

multi_arch_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]
)

전환 연결하기

엔드 투 엔드 예시

전환은 들어오는 가장자리와 나가는 가장자리라는 두 위치에 연결될 수 있습니다. 이는 사실상 규칙에서 자체 구성( 그리고 해당 종속 항목의 종속 항목을 구성 (발신 합니다.

참고: 현재 Starlark 전환을 네이티브 규칙에 연결할 수 있는 방법은 없습니다. 이 작업이 필요한 경우 bazel-discuss@googlegroups.com 에 문의하세요.

수신 에지 전환

들어오는 가장자리 전환은 transition 객체를 연결하여 활성화합니다. (transition()에 의해 생성됨)을 rule()cfg 매개변수에 추가합니다.

# example/rules.bzl
load("example/transitions:transitions.bzl", "hot_chocolate_transition")
drink_rule = rule(
    implementation = _impl,
    cfg = hot_chocolate_transition,
    ...

들어오는 가장자리 전환은 1:1 전환이어야 합니다.

바깥쪽 가장자리 전환

외부 가장자리 전환은 transition 객체를 연결하여 활성화합니다. (transition()로 생성됨)을 속성의 cfg 매개변수에 추가합니다.

# example/rules.bzl
load("example/transitions:transitions.bzl", "coffee_transition")
drink_rule = rule(
    implementation = _impl,
    attrs = { "dep": attr.label(cfg = coffee_transition)}
    ...

바깥쪽 가장자리 전환은 1:1 또는 1:2+일 수 있습니다.

전환으로 속성 액세스를 참고하세요. 이 키를 읽는 방법에 대해 알아보겠습니다.

네이티브 옵션 전환

엔드 투 엔드 예시

또한 Starlark 전환은 네이티브 빌드에서 읽기 및 쓰기를 선언할 수 있습니다. 구성 옵션을 추가할 수 있습니다.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {"//command_line_option:cpu": "k8"}

cpu_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]

지원되지 않는 네이티브 옵션

Bazel은 다음을 사용한 --define 전환을 지원하지 않습니다. "//command_line_option:define"입니다. 대신 빌드 설정을 참조하세요. 일반적으로 --define는 빌드 설정으로 사용하지 않는 것이 좋습니다.

Bazel은 --config에서의 전환을 지원하지 않습니다. 이는 --config가 '확장' 다른 플래그로 확장되는 플래그입니다.

결정적으로 --config에는 빌드 구성에 영향을 주지 않는 플래그가 포함될 수 있습니다. 예: --spawn_strategy 에서 자세한 내용을 확인하실 수 있습니다. 설계상 Bazel은 이러한 플래그를 개별 대상에 바인딩할 수 없습니다. 다시 말해 전환에 적용할 수 있는 일관된 방법이 없습니다.

이 문제를 해결하려면 다음을 포함하는 플래그를 명시적으로 항목화하면 됩니다. 구성을 변경할 수 있습니다 이를 위해서는 --config의 두 곳에서 확장되는 것인데, 이는 알려진 UI 결함입니다.

여러 빌드 허용 설정의 전환

빌드 설정을 지정할 때 여러 값 허용인 경우 목록을 사용하여 설정해야 합니다.

# example/buildsettings/build_settings.bzl
string_flag = rule(
    implementation = _impl,
    build_setting = config.string(flag = True, allow_multiple = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "string_flag")
string_flag(name = "roasts", build_setting_default = "medium")
# example/transitions/rules.bzl
def _transition_impl(settings, attr):
    # Using a value of just "dark" here will throw an error
    return {"//example:roasts" : ["dark"]},

coffee_transition = transition(
    implementation = _transition_impl,
    inputs = [],
    outputs = ["//example:roasts"]
)

무작동 전환

전환이 {}, [] 또는 None를 반환하면 이 코드는 설정을 원래대로 유지합니다. 이는 명시적으로 하는 것보다 더 편리할 수 있습니다. 각 출력을 자체적으로 설정해야 합니다

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (attr)
    if settings["//example:already_chosen"] is True:
      return {}
    return {
      "//example:favorite_flavor": "dark chocolate",
      "//example:include_marshmallows": "yes",
      "//example:desired_temperature": "38C",
    }

hot_chocolate_transition = transition(
    implementation = _impl,
    inputs = ["//example:already_chosen"],
    outputs = [
        "//example:favorite_flavor",
        "//example:include_marshmallows",
        "//example:desired_temperature",
    ]
)

전환으로 속성 액세스

엔드 투 엔드 예시

발신 에지에 전환을 연결할 때 (전환이 1:1인지 1:2+ 전환인지와 관계없이) ctx.attr는 목록이 되어야 합니다. 선택할 수 있습니다 이 목록의 요소 순서는 지정되지 않았습니다.

# example/transitions/rules.bzl
def _transition_impl(settings, attr):
    return {"//example:favorite_flavor" : "LATTE"},

coffee_transition = transition(
    implementation = _transition_impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

def _rule_impl(ctx):
    # Note: List access even though "dep" is not declared as list
    transitioned_dep = ctx.attr.dep[0]

    # Note: Access doesn't change, other_deps was already a list
    for other_dep in ctx.attr.other_deps:
      # ...


coffee_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "dep": attr.label(cfg = coffee_transition)
        "other_deps": attr.label_list(cfg = coffee_transition)
    })

전환이 1:2+이고 커스텀 키를 설정하면 ctx.split_attr를 사용할 수 있습니다. 각 키의 개별 deps를 읽습니다.

# example/transitions/rules.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {
        "Apple deps": {"//command_line_option:cpu": "ppc"},
        "Linux deps": {"//command_line_option:cpu": "x86"},
    }

multi_arch_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]
)

def _rule_impl(ctx):
    apple_dep = ctx.split_attr.dep["Apple deps"]
    linux_dep = ctx.split_attr.dep["Linux deps"]
    # ctx.attr has a list of all deps for all keys. Order is not guaranteed.
    all_deps = ctx.attr.dep

multi_arch_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "dep": attr.label(cfg = multi_arch_transition)
    })

전체 예 보기 여기에서 확인하세요.

플랫폼 및 도구 모음과 통합

현재 --cpu, --crosstool_top 등의 여러 자국어 신고와 관련이 있습니다. 툴체인 해상도입니다. 앞으로는 이러한 유형의 플래그가 타겟 플랫폼입니다.

메모리 및 성능 고려사항

빌드에 전환을 추가하여 새 구성을 추가하면 비용: 더 큰 빌드 그래프와 이해하기 어려운 빌드 그래프, 더 느린 속도 살펴보겠습니다 이러한 비용을 고려할 때 여러 가지 방법을 알아보겠습니다. 다음은 전환과 관련된 빌드 그래프가 기하급수적으로 증가할 수 있습니다

비정상적인 동작 빌드: 사례 연구

확장성 그래프

그림 1. 최상위 대상과 그 종속 항목을 보여주는 확장성 그래프

이 그래프는 최상위 타겟인 //pkg:app을 보여주며, 이 타겟은 //pkg:1_0//pkg:1_1. 이러한 타겟 모두 //pkg:2_0//pkg:2_1입니다. 두 타겟 모두 //pkg:3_0//pkg:3_1라는 두 타겟에 종속됩니다. 이는 //pkg:n_0//pkg:n_1까지 계속되며, 둘 다 단일 타겟, //pkg:dep.

//pkg:app 빌드에는 \(2n+2\) 타겟이 필요합니다.

  • //pkg:app
  • //pkg:dep
  • \([1..n]\)에서 \(i\) //pkg:i_0//pkg:i_1

플래그를 구현한다고 가정해 보겠습니다. --//foo:owner=<STRING>//pkg:i_b이(가) 적용됩니다.

depConfig = myConfig + depConfig.owner="$(myConfig.owner)$(b)"

즉, //pkg:i_b는 모든 항목의 이전 값 --ownerb을 추가합니다. deps.

그러면 다음과 같은 구성된 대상이 생성됩니다.

//pkg:app                              //foo:owner=""
//pkg:1_0                              //foo:owner=""
//pkg:1_1                              //foo:owner=""
//pkg:2_0 (via //pkg:1_0)              //foo:owner="0"
//pkg:2_0 (via //pkg:1_1)              //foo:owner="1"
//pkg:2_1 (via //pkg:1_0)              //foo:owner="0"
//pkg:2_1 (via //pkg:1_1)              //foo:owner="1"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_0)  //foo:owner="00"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_1)  //foo:owner="01"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_0)  //foo:owner="10"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_1)  //foo:owner="11"
...

//pkg:dep는 \(2^n\) 구성된 대상을 생성합니다. config.owner= '\(b_0b_1...b_n\)' 전체 \(b_i\) \(\{0,1\}\)

이렇게 하면 빌드 그래프가 대상 그래프보다 기하급수적으로 커지며 영향을 받게 됩니다.

할 일: 이러한 문제를 측정하고 완화하기 위한 전략을 추가합니다.

추가 자료

빌드 구성 수정에 관한 자세한 내용은 다음을 참고하세요.