이 페이지에서는 관점 사용의 기본사항과 이점을 설명하고 간단한 예시와 고급 예시가 있습니다.
추가 정보로 빌드 종속 항목 그래프를 보강할 수 있는 관점 실행할 수 있습니다 관점이 유용할 수 있는 일반적인 시나리오는 다음과 같습니다.
- Bazel을 통합하는 IDE는 관점을 사용하여 살펴보겠습니다
- 코드 생성 도구는 여러 측면을 활용하여
타겟에 구애받지 않는 방식으로 작동합니다. 예를 들어
BUILD
파일은 계층 구조를 지정할 수 있습니다. protobuf 라이브러리 정의, 언어별 규칙은 관점을 사용하여 특정 언어의 protobuf 지원 코드를 생성하는 작업
관점 기본사항
BUILD
파일은 프로젝트의 소스 코드에 대한 설명을 제공합니다.
파일이 프로젝트의 일부인 경우 빌드해야 하는 아티팩트 (대상)
이러한 파일 간의 종속 항목 등을 파악할 수 있습니다. Bazel은
이 정보를 사용하여 빌드를 수행합니다. 즉, 빌드하려는
아티팩트를 생성하는 데 필요한 (예: 컴파일러 또는 링커 실행)
해당 작업을 실행합니다. 이를 위해 Bazel은 종속 항목을 구성합니다.
그래프를 보고 이 그래프를 방문하여 해당 액션을 수집합니다.
다음 BUILD
파일을 살펴보세요.
java_library(name = 'W', ...)
java_library(name = 'Y', deps = [':W'], ...)
java_library(name = 'Z', deps = [':W'], ...)
java_library(name = 'Q', ...)
java_library(name = 'T', deps = [':Q'], ...)
java_library(name = 'X', deps = [':Y',':Z'], runtime_deps = [':T'], ...)
이 BUILD
파일은 다음 그림과 같이 종속 항목 그래프를 정의합니다.
그림 1. BUILD
파일 종속 항목 그래프
Bazel은 다음과 같은 구현 함수를 호출하여 이 종속 항목 그래프를 분석합니다.
해당 규칙 (이 경우 'java_library')을
타겟으로 설정합니다. 규칙 구현 함수는
.jar
파일과 같은 빌드 아티팩트 및 위치와 같은 정보 전달
이러한 아티팩트의 이름과 이름을 변경하여
제공업체.
관점은 규칙을 구성하는 데 도움이 되는 구현 함수가 있다는 점에서 작업을 생성하고 제공자를 반환합니다. 하지만 그 힘은 종속 항목 그래프가 빌드된 방식을 확인할 수 있습니다 관점에는 구현이 있습니다. 함께 전파되는 모든 속성 목록이 있습니다. 다음과 같은 측면 A를 생각해 보세요. 'deps'라는 속성을 따라 전파됩니다. 이 관점은 다음에 적용될 수 있습니다. 타겟 X를 생성하여 관점 애플리케이션 노드 A(X)를 생성합니다. 적용 과정에서 관점 A는 X가 'deps'에서 참조하는 모든 타겟에 재귀적으로 적용됨 속성 (A의 전파 목록에 있는 모든 속성)
따라서 대상 X에 관점 A를 적용하는 단일 행동은 '그림자 그래프'를 생성함 / 대상의 원래 종속 항목 그래프는 다음 그림과 같습니다.
그림 2. 관점으로 그래프를 빌드합니다.
그림자로 표시되는 유일한 가장자리는
전파 집합이기 때문에 여기서 runtime_deps
가장자리는 섀도 처리되지 않습니다.
예로 들 수 있습니다 그러면 관점 구현 함수가
노드에서 규칙 구현이 호출되는 방식과 유사한 그림자 그래프
원래 그래프의 일부분입니다.
간단한 예시
이 예에서는
규칙 및 deps
속성이 있는 모든 종속 항목을 포함합니다. 표시
관점 구현, 관점 정의, 관점을 호출하는 방법
gcloud 명령어입니다
def _print_aspect_impl(target, ctx):
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the files that make up the sources and
# print their paths.
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
print(f.path)
return []
print_aspect = aspect(
implementation = _print_aspect_impl,
attr_aspects = ['deps'],
)
예시를 여러 부분으로 나누어 각각 개별적으로 살펴보겠습니다.
관점 정의
print_aspect = aspect(
implementation = _print_aspect_impl,
attr_aspects = ['deps'],
)
관점 정의는 규칙 정의와 비슷하며,
aspect
함수
규칙과 마찬가지로 측면에는 구현 함수가 있습니다. 이 경우에는
_print_aspect_impl
attr_aspects
는 관점이 전파되는 규칙 속성 목록입니다.
이 경우 관점은 속성의 deps
속성을 따라
적용됩니다.
attr_aspects
의 또 다른 일반적인 인수는 ['*']
로,
특성을 정의하는 것입니다.
관점 구현
def _print_aspect_impl(target, ctx):
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the files that make up the sources and
# print their paths.
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
print(f.path)
return []
관점 구현 함수는 규칙 구현과 유사함 함수와 비교합니다. 제공업체를 반환하며 작업을 수행하며 다음 두 인수를 사용합니다.
구현 함수는
ctx.rule.attr
이 도구는 네트워크에 연결되어 있지 않은
적용되는 타겟에서 제공합니다 (target
인수를 통해).
제공업체 목록을 반환하려면 관점이 필요합니다. 이 예에서 아무것도 제공하지 않으므로 빈 목록을 반환합니다.
명령줄을 사용하여 관점 호출
관점을 적용하는 가장 간단한 방법은 명령줄에서
--aspects
드림
인수입니다. 위의 관점이 print.bzl
이라는 파일에 정의되었다고 가정합니다.
다음과 같습니다.
bazel build //MyExample:example --aspects print.bzl%print_aspect
은 print_aspect
을 대상 example
및 모든
deps
속성을 통해 재귀적으로 액세스할 수 있는 대상 규칙
--aspects
플래그는 관점 사양인 인수 1개를 사용합니다.
<extension file label>%<aspect top-level name>
형식으로 되어 있습니다.
고급 예시
다음 예시는 대상 규칙의 관점을 사용하는 방법을 보여줍니다. 대상의 파일을 세어, 잠재적으로 확장자별로 필터링할 수 있습니다. 제공자를 사용하여 값을 반환하는 방법, 매개변수를 사용하여 관점 구현에 대한 인수, 규칙에서 관점을 호출하는 방법을 설명합니다.
file_count.bzl
파일:
FileCountInfo = provider(
fields = {
'count' : 'number of files'
}
)
def _file_count_aspect_impl(target, ctx):
count = 0
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the sources counting files
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
count = count + 1
# Get the counts from our dependencies.
for dep in ctx.rule.attr.deps:
count = count + dep[FileCountInfo].count
return [FileCountInfo(count = count)]
file_count_aspect = aspect(
implementation = _file_count_aspect_impl,
attr_aspects = ['deps'],
attrs = {
'extension' : attr.string(values = ['*', 'h', 'cc']),
}
)
def _file_count_rule_impl(ctx):
for dep in ctx.attr.deps:
print(dep[FileCountInfo].count)
file_count_rule = rule(
implementation = _file_count_rule_impl,
attrs = {
'deps' : attr.label_list(aspects = [file_count_aspect]),
'extension' : attr.string(default = '*'),
},
)
BUILD.bazel
파일:
load('//:file_count.bzl', 'file_count_rule')
cc_library(
name = 'lib',
srcs = [
'lib.h',
'lib.cc',
],
)
cc_binary(
name = 'app',
srcs = [
'app.h',
'app.cc',
'main.cc',
],
deps = ['lib'],
)
file_count_rule(
name = 'file_count',
deps = ['app'],
extension = 'h',
)
관점 정의
file_count_aspect = aspect(
implementation = _file_count_aspect_impl,
attr_aspects = ['deps'],
attrs = {
'extension' : attr.string(values = ['*', 'h', 'cc']),
}
)
이 예에서는 deps
속성을 통해 관점이 전파되는 방식을 보여줍니다.
attrs
는 관점의 속성 집합을 정의합니다. 공개 관점 속성
string
유형이며 매개변수라고 합니다. 매개변수에는 values
이(가) 있어야 합니다.
속성을 지정해야 합니다. 이 예시에는 extension
라는 매개변수가 있습니다.
'*
', 'h
' 또는 'cc
'를 포함할 수 있는 항목 값으로 입력합니다.
관점의 매개변수 값은
관점을 요청하는 규칙의 이름입니다 (file_count_rule
정의 참고).
매개변수가 있는 관점은
문법을 사용하여 매개변수를 정의합니다.
또한 관점에는 label
또는
label_list
입니다. 비공개 라벨 속성을 사용하여
관점에 의해 생성된 작업에 필요한 도구나 라이브러리. 없음
다음 코드 스니펫은 이 예제에 정의되어 있는 비공개 속성입니다.
는 도구를 한 측면에 전달할 수 있는 방법을 보여줍니다.
...
attrs = {
'_protoc' : attr.label(
default = Label('//tools:protoc'),
executable = True,
cfg = "exec"
)
}
...
관점 구현
FileCountInfo = provider(
fields = {
'count' : 'number of files'
}
)
def _file_count_aspect_impl(target, ctx):
count = 0
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the sources counting files
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
count = count + 1
# Get the counts from our dependencies.
for dep in ctx.rule.attr.deps:
count = count + dep[FileCountInfo].count
return [FileCountInfo(count = count)]
규칙 구현 함수와 마찬가지로, 관점 구현 함수는 종속 항목에 액세스할 수 있는 제공자의 구조체를 반환합니다.
이 예에서 FileCountInfo
는
count
필드 포드의 필드를 명시적으로 정의하는 것이
공급자에게 fields
속성을 사용합니다.
관점 애플리케이션 A(X)의 제공자 집합은 제공자의 합집합입니다.
타겟 X에 대한 규칙을 구현하고
관점 A의 구현. 규칙 구현이 전파되는 제공업체
관점이 적용되기 전에 생성되고 고정되며
측면입니다 타겟과 해당 타겟에 각각 적용되는 관점이 있으면 오류입니다.
는 다음을 제외하고 동일한 유형의 제공자를 제공합니다.
OutputGroupInfo
드림
(
규칙과 관점이 서로 다른 출력 그룹을 지정)
InstrumentedFilesInfo
(측면에서 가져옴) 즉, 관점 구현은
절대 DefaultInfo
를 반환하지 않습니다.
매개변수와 비공개 속성은
ctx
이 예에서는 extension
매개변수를 참조하고
지정할 수 있습니다.
제공자를 반환하는 경우
attr_aspects
목록에서 표시되는 관점이 다음으로 대체됩니다.
살펴봤습니다 예를 들어
X의 deps에 Y와 Z가 있으며, A(X)의 ctx.rule.attr.deps
은 [A(Y), A(Z)]입니다.
이 예에서 ctx.rule.attr.deps
는
'deps'에 관점을 적용한 결과 원래 타겟의
관점이 적용되었습니다
이 예에서는 관점이 FileCountInfo
제공자에 액세스합니다.
전체 과도적 파일 수를 축적할 수 있습니다.
규칙에서 관점 호출
def _file_count_rule_impl(ctx):
for dep in ctx.attr.deps:
print(dep[FileCountInfo].count)
file_count_rule = rule(
implementation = _file_count_rule_impl,
attrs = {
'deps' : attr.label_list(aspects = [file_count_aspect]),
'extension' : attr.string(default = '*'),
},
)
규칙 구현은 FileCountInfo
에 액세스하는 방법을 보여줍니다.
ctx.attr.deps
을 통해 전달됩니다.
규칙 정의는 매개변수 (extension
)를 정의하는 방법을 보여줍니다.
기본값 (*
)을 지정합니다. 이 작업은
'cc
', 'h
' 또는 '*
' 중 하나가 아님 인코더가 생성한
관점 정의에서 매개변수에 배치된 제한사항
대상 규칙을 통해 관점 호출
load('//:file_count.bzl', 'file_count_rule')
cc_binary(
name = 'app',
...
)
file_count_rule(
name = 'file_count',
deps = ['app'],
extension = 'h',
)
extension
매개변수를 관점에 전달하는 방법을 보여줍니다.
광고를 게재할 수 있습니다. extension
매개변수의 기본값은
extension
는 선택적 매개변수로 간주됩니다.
file_count
타겟이 빌드되면 관점이 평가됩니다.
자체, 모든 타겟은 deps
를 통해 재귀적으로 액세스할 수 있습니다.