종속 항목

문제 신고 <ph type="x-smartling-placeholder"></ph> 소스 보기 1박 · 7.2 · 7.1 · 7.0 · 6.5 · 6.4

빌드 시 A에서 B가 필요한 경우 타겟 A는 타겟 B종속됩니다. 실행할 수 있습니다 종속 관계는 방향성 비순환 그래프 (DAG)를 정의하며 이를 종속 항목 그래프라고 합니다.

대상의 직접 종속 항목은 경로를 통해 도달할 수 있는 다른 대상입니다. 길이 1의 길이 1보다 짧습니다. 대상의 전이 종속 항목은 다음과 같습니다. 그래프를 통한 모든 길이의 경로를 통해 종속되는 타겟의 가중치를 부여합니다.

실제로 빌드 컨텍스트에는 두 가지 종속 항목 그래프가 있습니다. 실제 종속 항목선언된 종속 항목 그래프 대부분의 두 그래프가 매우 유사해서 이 두 가지를 구분할 필요는 없지만, 아래 논의에서 유용할 것입니다.

실제 종속 항목과 선언된 종속 항목

Y가 있어야 하는 경우 타겟 X은 타겟 Y실제로 종속됩니다. X가 올바르게 빌드되려면 최신 버전이어야 합니다. Built(빌드)는 생성, 처리, 컴파일, 링크, 보관처리, 압축, 실행 또는 빌드 중에 일상적으로 발생하는 다른 모든 종류의 작업입니다.

종속 항목이 있는 경우 타겟 X에 타겟 Y선언된 종속 항목이 있음 X의 가장자리를 X에서 Y로 업데이트합니다.

올바른 빌드를 위해서는 실제 종속 항목 A의 그래프가 아래의 하위 그래프여야 합니다. 선언된 종속 항목 D의 그래프입니다. 즉, A의 직접 연결된 노드(x --> y)도 다음 위치에서 직접 연결되어야 합니다. D DA과대근사라고 말할 수 있습니다.

BUILD 파일 작성기는 모든 실제 직접 빌드 시스템에 대한 모든 규칙의 종속 항목이며 그 이상은 허용되지 않습니다.

이 원칙을 준수하지 않으면 정의되지 않은 동작이 발생합니다. 즉, 빌드가 실패할 수 있고 더 나쁜 것은 빌드가 이전 작업 또는 전이적 작업에 종속될 수 있다는 것입니다. 종속 항목을 선언합니다. Bazel이 누락 여부를 확인 오류를 보고하지만 이 검사는 모든 경우에 완료됩니다

간접적으로 가져온 모든 것을 나열하려고 하거나 시도해서는 안 됩니다. 이는 실행 시 A에 의해 필요하더라도 마찬가지입니다.

타겟 X의 빌드 중에 빌드 도구는 전체 전이 요소를 검사합니다. 타겟의 변경사항이 적용되도록 X의 종속 항목 클로저 최종 결과에 반영되며 필요에 따라 중간 항목을 다시 빌드합니다.

종속 항목의 전이적 특성으로 인해 흔히 범하는 실수가 발생합니다. 가끔 간접 종속 항목에서 제공하는 코드를 사용할 수도 있습니다. 선언된 종속 항목 그래프에서 전이성이지만 직속 에지는 아닙니다. 간접 종속 항목은 BUILD 파일에 표시되지 않습니다. 규칙은 제공업체에 직접 종속되어 있으므로 변경사항을 추적할 방법이 없습니다(아래 참고). 타임라인 예는 다음과 같습니다.

1. 선언된 종속 항목이 실제 종속 항목과 일치

처음에는 모든 것이 제대로 작동합니다. a 패키지의 코드는 b 패키지의 코드를 사용합니다. 패키지 b의 코드가 c 패키지의 코드를 사용하므로 a가 전이적으로 사용됩니다. c에 종속됩니다.

a/BUILD b/BUILD
rule(
    name = "a",
    srcs = "a.in",
    deps = "//b:b",
)
      
rule(
    name = "b",
    srcs = "b.in",
    deps = "//c:c",
)
      
a / a.in b / b.in
import b;
b.foo();
    
import c;
function foo() {
  c.bar();
}
      
a, b, c를 연결하는 화살표가 있는 선언된 종속 항목 그래프
선언된 종속 항목 그래프
선언된 종속 항목과 일치하는 실제 종속 항목 그래프
                  a, b, c를 연결하는 화살표가 있는 그래프
실제 종속 항목 그래프

선언된 종속 항목이 실제 종속 항목에 가깝습니다. 잘 지내고 있습니다.

2. 선언되지 않은 종속 항목 추가

누군가 a에 코드를 추가하면 잠재 위험이 발생합니다. c에 대한 직접적인 실제 종속 항목을 사용하지만 빌드 파일에서 이를 선언하는 것을 잊어버림 a/BUILD입니다.

a / a.in  
        import b;
        import c;
        b.foo();
        c.garply();
      
 
a, b, c를 연결하는 화살표가 있는 선언된 종속 항목 그래프
선언된 종속 항목 그래프
a, b, c를 연결하는 화살표가 있는 실제 종속 항목 그래프 
                  화살표는 이제 A와 C를 연결합니다. 이것은
                  선언된 종속 항목 그래프
실제 종속 항목 그래프

선언된 종속 항목이 더 이상 실제 종속 항목에 과대근접하지 않습니다. 두 그래프의 전이 종결이 동일하기 때문에 이 경우 문제가 없을 수 있습니다. 하지만 문제를 가립니다. a에는 실제로 선언되지 않은 c의 종속 항목이 있습니다.

3. 선언된 종속 항목 그래프와 실제 종속 항목 그래프 간의 차이

누군가 b를 리팩터링하여 더 이상 종속되지 않도록 하면 위험이 드러납니다. c, 의도치 않게 a에서 아니요로 중단 스스로의 잘못일 수 있습니다

  b/BUILD
 
rule(
    name = "b",
    srcs = "b.in",
    deps = "//d:d",
)
      
  b / b.in
 
      import d;
      function foo() {
        d.baz();
      }
      
a와 b를 연결하는 화살표가 있는 선언된 종속 항목 그래프
                  b는 더 이상 c에 연결되지 않아 a와 c의 연결이 끊어집니다.
선언된 종속 항목 그래프
A가 b와 c에 연결되어 있음을 보여주는 실제 종속 항목 그래프
                  그러나 b는 더 이상 c에 연결되지 않습니다.
실제 종속 항목 그래프

선언된 종속 항목 그래프는 이제 실제 종속 항목(전이적으로 닫힌 경우에도) 빌드가 실패할 가능성이 높습니다

이 문제는 2단계에서 도입된 a~cBUILD 파일에서 올바르게 선언되었습니다.

종속 항목 유형

대부분의 빌드 규칙에는 다양한 종류의 객체를 지정하기 위한 세 가지 속성이 있습니다. 일반 종속 항목: srcs, deps, data 이에 대해서는 아래에 설명되어 있습니다. 대상 자세한 내용은 모든 규칙의 공통 속성

또한 많은 규칙에는 종속 항목(예: compiler 또는 resources) 자세한 내용은 백과사전 만들기

종속 항목 srcs

규칙 또는 소스 파일을 출력하는 규칙에서 직접 사용하는 파일입니다.

종속 항목 deps

헤더 파일을 제공하는 별도로 컴파일된 모듈을 가리키는 규칙 기호, 라이브러리, 데이터 등입니다.

종속 항목 data

빌드 타겟이 올바르게 실행되려면 일부 데이터 파일이 필요할 수 있습니다. 이러한 데이터 파일은 타겟이 빌드되는 방식에 영향을 주지 않습니다. 예를 들어 단위 테스트는 함수의 출력을 파일의 콘텐츠와 비교할 수 있습니다. 파일이 필요하지 않은 단위 테스트를 빌드하고 있습니다. 실행 중에 실행되는 도구도 마찬가지입니다.

빌드 시스템은 data은(는) 사용 가능합니다. 따라서 바이너리/라이브러리/테스트를 실행하기 위해 일부 파일이 필요한 경우 data에서 이러한 항목 (또는 이를 포함하는 빌드 규칙)을 지정할 수 있습니다. 예를 들면 다음과 같습니다.

# I need a config file from a directory named env:
java_binary(
    name = "setenv",
    ...
    data = [":env/default_env.txt"],
)

# I need test data from another directory
sh_test(
    name = "regtest",
    srcs = ["regtest.sh"],
    data = [
        "//data:file1.txt",
        "//data:file2.txt",
        ...
    ],
)

이러한 파일은 상대 경로 path/to/data/file를 사용하여 사용할 수 있습니다. 테스트에서 테스트 소스의 경로를 조인하여 이 파일을 참조할 수 있습니다. 디렉터리 및 작업공간 상대 경로(예: ${TEST_SRCDIR}/workspace/path/to/data/file

라벨을 사용하여 디렉터리 참조

BUILD 파일을 살펴보면 일부 data 라벨이 있음을 알 수 있습니다. 디렉터리 참조 이러한 라벨은 다음 예와 같이 /. 또는 /로 끝납니다. 다음과 같은 형식을 사용하면 안 됩니다.

권장하지 않음 — <ph type="x-smartling-placeholder">data = ["//data/regression:unittest/."]</ph>

권장하지 않음 — <ph type="x-smartling-placeholder">data = ["testdata/."]</ph>

권장하지 않음 — <ph type="x-smartling-placeholder">data = ["testdata/"]</ph>

이는 특히 테스트에서 편리해 보입니다. 디렉터리의 모든 데이터 파일을 사용합니다

하지만 그렇게 하지 마세요. 올바른 증분 재빌드 (및 빌드 시스템이 변경 후 빌드 (또는 테스트)에 대한 입력인 전체 파일 세트입니다. 클러스터 수준에서 빌드 시스템은 디렉터리 자체가 변경 사항 (파일 추가 또는 삭제로 인한 변경)이 있지만, 개별 파일에 대한 수정사항은 포함된 디렉터리에 영향을 미치지 않기 때문입니다. 디렉터리를 빌드 시스템에 입력으로 지정하는 대신 명시적으로 또는 glob() 함수 **를 사용하여 glob()는 재귀적이어야 합니다.)

권장 - <ph type="x-smartling-placeholder">data = glob(["testdata/**"])</ph>

하지만 디렉터리 라벨을 사용해야 하는 경우가 몇 가지 있습니다. 예를 들어 testdata 디렉터리에 이름이 라벨 구문 준수 파일을 명시적으로 열거하거나 glob() 함수가 잘못된 라벨을 생성함 오류가 발생했습니다. 이 경우 디렉토리 라벨을 사용해야 하지만 잘못된 재빌드로 인한 위험과 관련된 위험을 감시할 수 있습니다

디렉터리 라벨을 사용해야 하는 경우 상대 ../ 경로가 있는 상위 패키지 대신 //data/regression:unittest/.입니다.

여러 파일을 사용해야 하는 모든 외부 규칙(예: 테스트)은 모든 클래스에 대한 종속성을 명시적으로 선언합니다. filegroup()를 사용하여 다음 작업을 할 수 있습니다. 다음과 같이 BUILD 파일에서 파일을 함께 그룹화합니다.

filegroup(
        name = 'my_data',
        srcs = glob(['my_unittest_data/*'])
)

그런 다음 테스트에서 데이터 종속 항목으로 my_data 라벨을 참조할 수 있습니다.

BUILD 파일 가시성