Bazel을 사용하여 프로그램 빌드

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

이 페이지에서는 Bazel을 사용하여 프로그램을 빌드하는 방법과 명령어 문법을 빌드하는 방법을 설명합니다. 대상 패턴 문법을 사용합니다.

빠른 시작

Bazel을 실행하려면 기본 workspace 디렉터리로 이동합니다. 또는 하위 디렉터리 중 하나를 선택하고 bazel 유형을 사용하세요. 다음 경우에는 빌드를 참고하세요. 새 작업공간을 만들어야 합니다

bazel help
                             [Bazel release bazel version]
Usage: bazel command options ...

사용할 수 있는 명령어

  • analyze-profile: 빌드 프로필 데이터를 분석합니다.
  • aquery: 분석 후 작업 그래프에서 쿼리를 실행합니다.
  • build: 지정된 타겟을 빌드합니다.
  • canonicalize-flags: Bazel 플래그를 표준화합니다.
  • clean: 출력 파일을 삭제하고 선택적으로 서버를 중지합니다.
  • cquery: 분석 후 종속 항목 그래프 쿼리를 실행합니다.
  • dump: Bazel 서버 프로세스의 내부 상태를 덤프합니다.
  • help: 명령어 또는 색인에 대한 도움말을 출력합니다.
  • info: bazel 서버에 대한 런타임 정보를 표시합니다.
  • fetch: 대상의 모든 외부 종속 항목을 가져옵니다.
  • mobile-install: 휴대기기에 앱을 설치합니다.
  • query: 종속 항목 그래프 쿼리를 실행합니다.
  • run: 지정된 타겟을 실행합니다.
  • shutdown: Bazel 서버를 중지합니다.
  • test: 지정된 테스트 대상을 빌드하고 실행합니다.
  • version: Bazel의 버전 정보를 출력합니다.

도움 받기

  • bazel help command: 다음에 관한 도움말 및 옵션을 출력합니다. command
  • bazel helpstartup_options: Bazel을 호스팅하는 JVM의 옵션입니다.
  • bazel helptarget-syntax: 타겟을 지정하는 문법을 설명합니다.
  • bazel help info-keys: 정보 명령어에서 사용하는 키 목록을 표시합니다.

bazel 도구는 명령어라는 여러 기능을 실행합니다. 가장 일반적으로 bazel buildbazel test입니다. 온라인 도움말을 탐색하여 bazel help를 사용하여 메시지를 보냅니다.

단일 대상 구축

빌드를 시작하려면 작업공간이 필요합니다. 작업공간은 빌드에 필요한 모든 소스 파일이 포함된 디렉터리 트리 애플리케이션입니다. Bazel을 사용하면 완전한 읽기 전용으로 볼륨

Bazel을 사용하여 프로그램을 빌드하려면 bazel build타겟을 선택합니다.

bazel build //foo

//foo를 빌드하는 명령어를 실행하면 다음과 비슷한 출력이 표시됩니다.

INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions

먼저 Bazel은 대상의 종속 항목 그래프에 모든 패키지를 로드합니다. 이 타겟의 BUILD에 직접 나열된 파일인 선언된 종속 항목 포함 파일 및 전이 종속성, 파일에 나열된 BUILD 파일에 종속 항목을 업데이트해야 합니다 모든 종속 항목을 식별한 후 Bazel은 이를 분석합니다. 빌드 작업을 생성합니다. 마지막으로 Bazel은 실행 빌드의 컴파일러 및 기타 도구에 적용됩니다.

Bazel은 빌드 실행 단계 중에 진행 메시지를 출력합니다. 진행 상황 메시지에는 현재 빌드 단계 (예: 컴파일러 또는 링커)가 포함됩니다. 총 빌드 작업 수 대비 완료된 횟수 이 Bazel이 코드를 빌드하면 총 작업 수가 액션 그래프 전체이지만 숫자는 몇 초 내에 안정화됩니다.

빌드가 끝나면 Bazel은 요청받은 대상을 출력합니다. 빌드되지 않은 경우, 빌드가 완료된 경우 출력 파일은 발견. 빌드를 실행하는 스크립트는 이 출력을 안정적으로 파싱할 수 있습니다. 보기 --show_result에서 자세한 내용을 확인하세요.

같은 명령어를 다시 입력하면 빌드가 훨씬 빨리 완료됩니다.

bazel build //foo
INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 0.144s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action

null 빌드입니다. 아무것도 변경되지 않았으므로 새로고침할 패키지가 없습니다. 실행할 빌드 단계가 없습니다 'foo'에 변경사항이 있는 경우 또는 Bazel은 일부 빌드 작업을 재실행하거나 증분 빌드를 지원합니다.

여러 대상 빌드

Bazel을 사용하면 여러 가지 방법으로 빌드할 대상을 지정할 수 있습니다. 총칭하여 이를 대상 패턴이라고 합니다. 이 구문은 build, test 또는 query입니다.

반면 라벨BUILD 파일에서 종속 항목을 선언하는 경우와 같이 Bazel의 대상은 패턴은 여러 타겟을 지정합니다 타겟 패턴은 타겟 세트에 대한 라벨 문법을 제공합니다. 가장 간단한 경우 유효한 레이블도 유효한 대상 패턴으로, 정확히 한 개의 집합을 식별하는 있습니다.

//(으)로 시작하는 모든 타겟 패턴이 현재 살펴보겠습니다

//foo/bar:wiz 단일 타겟 //foo/bar:wiz만 있으면 됩니다.
//foo/bar //foo/bar:bar와 같습니다.
//foo/bar:all foo/bar 패키지의 모든 규칙 대상
//foo/... foo 디렉터리 아래에 있는 모든 패키지의 모든 규칙 대상입니다.
//foo/...:all foo 디렉터리 아래에 있는 모든 패키지의 모든 규칙 대상입니다.
//foo/...:* foo 디렉터리 아래에 있는 모든 패키지의 모든 대상 (규칙 및 파일)입니다.
//foo/...:all-targets foo 디렉터리 아래에 있는 모든 패키지의 모든 대상 (규칙 및 파일)입니다.
//... 작업공간에 있는 패키지의 모든 대상입니다. 대상은 포함되지 않습니다. 외부 저장소에서 가져올 수 있습니다.
//:all 최상위 패키지에 `BUILD` 파일이 있는 경우 작업공간의 루트에 입력합니다.

//로 시작하지 않는 타겟 패턴은 현재 작업 디렉터리 이 예에서는 foo의 작업 디렉터리를 가정합니다.

:foo //foo:foo와 같습니다.
bar:wiz //foo/bar:wiz와 같습니다.
bar/wiz 다음과 같음: <ph type="x-smartling-placeholder">
    </ph>
  • foo/bar/wiz가 패키지인 경우 //foo/bar/wiz:wiz
  • foo/bar가 패키지인 경우 //foo/bar:wiz
  • 그 밖의 경우 //foo:bar/wiz
bar:all //foo/bar:all와 같습니다.
:all //foo:all와 같습니다.
...:all //foo/...:all와 같습니다.
... //foo/...:all와 같습니다.
bar/...:all //foo/bar/...:all와 같습니다.

기본적으로 재귀 대상 패턴에는 디렉터리 심볼릭 링크가 뒤따릅니다. 편의 작업공간의 루트 디렉터리에 생성된 심볼릭 링크를 생성합니다.

또한 Bazel은 재귀 타겟을 평가할 때 심볼릭 링크를 따르지 않습니다. . DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN

foo/...packages의 와일드 카드로, 모든 패키지를 재귀적으로 나타냅니다. foo 디렉토리 아래에 입력합니다 (패키지 경로의 모든 루트). :all: 패키지 내의 모든 규칙과 일치하는 대상에 대한 와일드 카드 이 두 가지는 foo/...:all에서와 같이 결합되며 두 와일드 카드를 모두 사용하는 경우 foo/...로 축약됩니다.

또한 :* (또는 :all-targets)는 모든 타겟과 일치하는 와일드 카드입니다. 일반적으로 어떤 규칙에도 빌드되지 않은 파일을 비롯하여 일치하는 패키지의 내 파일, 예를 들어 java_binary 규칙과 관련된 _deploy.jar 파일 등이 이에 해당합니다.

즉, :*:all상위 집합을 나타냅니다. 동시에 이 구문은 친숙한 :all 와일드 카드를 사용하여 _deploy.jar와 같은 타겟을 빌드하는 것은 바람직하지 않은 일반적인 빌드입니다.

또한 Bazel은 라벨 문법 이는 Bash 파일 이름 확장을 사용할 때 편리합니다. 예를 들어 foo/bar/wiz//foo/bar:wiz와 동일합니다( foo/bar 패키지) 또는 //foo:bar/wiz (foo 패키지가 있는 경우)로 전달됩니다.

많은 Bazel 명령어가 타겟 패턴 목록을 인수로 허용하며 접두사 부정 연산자 -를 적용합니다. 이 값을 사용하여 앞의 인수로 지정된 집합에서 대상을 반환합니다. 이는 질이 중요합니다. 예를 들면 다음과 같습니다.

bazel build foo/... bar/...

'foo 아래의 모든 타겟 bar 아래의 모든 타겟을 빌드'한다는 의미입니다.

bazel build -- foo/... -foo/bar/...

'foo/bar 아래의 대상을 제외한 foo 아래의 모든 타겟을 빌드'한다는 의미입니다. ( -로 시작하는 후속 인수를 방지하려면 -- 인수가 필요합니다. 추가 옵션으로 해석되지 않습니다.)

단, 이렇게 타겟을 빼도 타겟의 종속 항목일 수 있으므로 빌드되지 않음을 보장 40%가 차감됩니다. 예를 들어 타겟 //foo:all-apis가 있는 경우 //foo/bar:api에 종속된 경우 후자는 다음과 같이 빌드됩니다. 전자를 구축하는 과정의 일부입니다.

tags = ["manual"]인 대상은 와일드 카드 대상 패턴에 포함되지 않습니다. (..., :*, :all 등) bazel buildbazel test (하지만 제외 와일드 카드 타겟 패턴). 즉, 해당 패턴은 뺍니다. 해야 할 일 다음과 같은 경우 명령줄에서 명시적 타겟 패턴으로 이러한 테스트 타겟을 지정합니다. Bazel에서 빌드/테스트하도록 하세요. 반면에 bazel query는 이러한 필터링을 자동으로 수행할 수 있으며, 이는 bazel query)을 입력합니다.

외부 종속 항목 가져오기

기본적으로 Bazel은 코드 실행 중에 있습니다. 그러나 이는 바람직하지 않을 수 있습니다. 새 외부 종속 항목이 추가되거나 "미리 가져오기" 종속 항목 (예: 오프라인 상태가 되는 비행 전)을 할 수 없습니다. 만약 빌드 중에 새로운 종속 항목이 추가되지 않도록 하려면 --fetch=false 플래그를 지정할 수 있습니다. 이 플래그만 로컬의 디렉터리를 가리키지 않는 저장소 규칙에 적용됩니다. 파일 시스템입니다. 변경사항(예: local_repository) new_local_repository 및 Android SDK, NDK 저장소 규칙 --fetch 값에 관계없이 항상 적용됩니다 .

빌드 중에 가져오기를 허용하지 않고 Bazel이 새로운 외부 빌드가 실패합니다

bazel fetch를 실행하여 종속 항목을 수동으로 가져올 수 있습니다. 만약 빌드 가져오기를 허용하지 않도록 하려면 bazel fetch를 실행해야 합니다.

  • 처음 빌드하기 전
  • 새 외부 종속 항목을 추가한 후

일단 실행되면 WORKSPACE가 끝날 때까지 다시 실행할 필요가 없습니다. 파일 변경사항.

fetch는 종속 항목을 가져올 대상 목록을 가져옵니다. 대상 예를 들어 //foo:bar를 빌드하는 데 필요한 종속 항목을 가져옵니다. 및 //bar:baz:

bazel fetch //foo:bar //bar:baz

작업공간의 모든 외부 종속 항목을 가져오려면 다음을 실행합니다.

bazel fetch //...

Bazel 7.1 이상에서 Bzlmod를 사용 설정한 경우 다음을 실행하여 외부 종속 항목을

bazel fetch

사용 가능한 모든 도구가 있다면 Bazel 가져오기를 전혀 실행할 필요가 없습니다. (라이브러리 jar에서 JDK 자체로)를 사용하여 작업공간 루트에서 특정 객체를 선언합니다. 그러나 작업공간 디렉터리 외부의 항목을 사용하는 경우 Bazel이 을(를) 실행하기 전에 bazel fetch이(가) 자동으로 실행됩니다. bazel build

저장소 캐시

Bazel은 동일한 파일이 파일이 다른 작업공간에서 필요하거나 저장소가 변경되었지만 다운로드하려면 여전히 동일한 파일이 필요합니다. 이렇게 하려면 bazel은 저장소 캐시에 다운로드된 모든 파일을 캐시하며, 기본적으로 ~/.cache/bazel/_bazel_$USER/cache/repos/v1/에 있습니다. 이 위치는 --repository_cache 옵션으로 변경할 수 있습니다. 이 캐시는 모든 작업공간과 설치된 bazel 버전 간에 공유됩니다. 다음과 같은 경우 캐시에서 항목을 가져옵니다. Bazel은 올바른 파일의 복사본이 있는지, 즉 다운로드 요청에 지정된 파일의 SHA256 합계와 해시가 캐시에 있는지 확인합니다. 따라서 각 외부 파일에 대해 해시를 지정하는 것은 좋은 아이디어일 뿐만 아니라 또한 공격이 만들 수 있습니다.

캐시 적중 시 캐시에 있는 파일의 수정 시간은 이(가) 업데이트되었습니다. 이렇게 하면 캐시 디렉터리에 있는 파일의 마지막 사용이 수동으로 캐시를 정리하는 등의 작업을 수행해야 합니다. 캐시는 절대로 백업되지 않은 파일의 사본이 포함될 수 있으므로 자동으로 정리됩니다. 업스트림에서 사용할 수 있습니다.

배포 파일 디렉터리

배포 디렉터리는 불필요함을 방지하기 위한 또 다른 Bazel 메커니즘입니다. 있습니다. Bazel은 저장소 캐시 전에 배포 디렉터리를 검색합니다. 가장 큰 차이점은 배포 디렉터리에는 수동으로 준비할 수 있습니다

--distdir=/path/to-directory 드림 옵션을 사용하면 추가 읽기 전용 디렉터리를 지정하여 가져오는 대신 파일 이름이 URL의 기본 이름과 같고 추가적으로 파일의 해시가 다운로드 요청에 지정된 것과 같습니다. 이는 파일 해시는 WORKSPACE 선언에서 지정됩니다.

파일 이름의 조건은 정확성을 위해 필요하지는 않지만 후보 파일 수를 지정된 디렉터리당 한 개로 줄입니다 이 배포 파일 디렉토리를 지정하는 것이 이러한 디렉토리의 파일 수가 증가합니다.

에어갭 환경에서 Bazel 실행

Bazel의 바이너리 크기를 작게 유지하기 위해 Bazel의 암시적 종속 항목을 가져옵니다. 네트워크를 통해 트래픽을 전송 할 수 있습니다. 이러한 암시적 종속 항목은 일부 사용자에게만 필요한 도구 모음과 규칙을 포함합니다. 대상 예를 들어 Android 도구는 Android를 빌드할 때만 번들 해제되어 가져올 수 있습니다. 살펴보겠습니다

그러나 이러한 암시적 종속 항목은 실행할 때 문제를 일으킬 수 있습니다. Bazel을 에어갭 환경에서 사용할 수 있도록 WORKSPACE 종속 항목을 사용하는 것이 좋습니다 이 문제를 해결하려면 배포 디렉터리를 이러한 종속 항목을 포함하는 것은 네트워크 액세스가 가능한 머신에 오프라인 접근 방식을 사용하여 에어갭 환경으로 전송합니다.

배포 디렉터리를 준비하려면 다음을 사용합니다. --distdir 플래그. 새 Bazel 바이너리 버전마다 이 작업을 한 번씩 실행해야 하므로 암시적 종속 항목은 릴리스마다 다를 수 있습니다.

에어갭 환경 외부에서 이러한 종속 항목을 빌드하려면 먼저 올바른 버전의 Bazel 소스 트리를 확인하세요.

git clone https://github.com/bazelbuild/bazel "$BAZEL_DIR"
cd "$BAZEL_DIR"
git checkout "$BAZEL_VERSION"

그런 다음 암시적 런타임 종속 항목이 포함된 tarball을 빌드합니다. 특정 Bazel 버전:

bazel build @additional_distfiles//:archives.tar

에어갭 적용 시 복사할 수 있는 디렉터리로 이 tarball을 내보냅니다. 환경입니다 --distdir가 다음과 같을 수 있으므로 --strip-components 플래그를 확인합니다. 디렉터리 중첩 수준은 상당히 까다롭습니다.

tar xvf bazel-bin/external/additional_distfiles/archives.tar \
  -C "$NEW_DIRECTORY" --strip-components=3

마지막으로 에어갭 환경에서 Bazel을 사용할 때 --distdir를 전달합니다. 디렉터리를 가리키는 플래그입니다. 편의를 위해 .bazelrc로 추가할 수 있습니다. 항목:

build --distdir=path/to/directory

빌드 구성 및 크로스 컴파일

주어진 빌드의 동작과 결과를 지정하는 모든 입력은 크게 두 가지 카테고리로 나눌 수 있습니다 첫 번째 종류는 프로젝트의 BUILD 파일에 저장된 정보(빌드 규칙, 전체 종속 항목 집합을 정의합니다. 두 번째 종류는 외부 또는 환경 데이터로, 사용자 또는 빌드 도구: 대상 아키텍처, 컴파일, 링크 선택 옵션 및 기타 도구 모음 구성 옵션도 제공합니다. 인코더-디코더 아키텍처를 환경 데이터의 구성으로 표시됩니다.

빌드에는 2개 이상의 구성이 있을 수 있습니다. 예를 들어 크로스 컴파일 - 64비트용 //foo:bin 실행 파일을 빌드합니다. 워크스테이션은 32비트 머신입니다. 빌드는 확실히 64비트 생성이 가능한 도구 모음을 사용하여 //foo:bin를 빌드해야 함 하지만 빌드 시스템은 컨테이너 내에서 사용되는 다양한 도구도 예를 들어 소스에서 빌드된 도구를 빌드한 다음 예를 들어 genrule에 사용되며, 워크스테이션에서 실행되도록 빌드되어야 합니다. 따라서 두 가지 구성, 즉 exec configuration이라는 두 가지 구성을 식별할 수 있습니다. 빌드 중에 실행되는 도구 빌드 및 대상 구성 (또는 구성을 요청하지만, '대상 구성'이라고 하는 경우도 더 많습니다. 단어는 이미 많은 의미가 있음)은 바이너리를 가져올 수 있습니다.

일반적으로 요청된 API와 API를 사용하기 위한 전제 조건인 라이브러리가 빌드 타겟(//foo:bin) 및 하나 이상의 exec 도구(예: 기본 라이브러리를 제공합니다. 이러한 라이브러리는 exec를 위해 한 번, 총 두 번 빌드해야 합니다. 한 번은 대상 구성에 사용할 수 있습니다 Bazel이 맡아서 두 변형이 모두 빌드되고 파생된 파일이 유지되는지 확인 간섭을 방지하기 위해 분리 일반적으로 이러한 대상은 동시에 빌드될 수 있지만 서로 독립적이기 때문입니다. 진행률 메시지가 표시되는 경우 는 지정된 타겟이 두 번 빌드되고 있음을 나타냄으로써 가장 가능성이 크다는 것을 의미합니다. 설명

exec 구성은 다음과 같이 타겟 구성에서 파생됩니다.

  • 다음에 지정된 것과 동일한 버전의 Crosstool (--crosstool_top)을 사용합니다. 요청 구성(--host_crosstool_top가 지정되지 않은 경우)
  • --cpu--host_cpu 값을 사용합니다 (기본값: k8).
  • 이 옵션의 값을 요청에 지정된 것과 동일한 값을 사용하세요. 구성: --compiler, --use_ijars, --host_crosstool_top가 다음에 해당하는 경우 가 사용되는 경우 --host_cpu 값은 exec에 관한 Crosstool의 default_toolchain (--compiler 무시) 구성할 수 있습니다
  • --javabase--host_javabase 값을 사용합니다.
  • --java_toolchain--host_java_toolchain 값을 사용합니다.
  • C++ 코드에 최적화된 빌드를 사용합니다 (-c opt).
  • 디버깅 정보를 생성하지 않습니다 (--copt=-g0).
  • 실행 파일과 공유 라이브러리에서 디버그 정보 제거 (--strip=always)
  • 모든 파생 파일을 모든 가능한 요청 구성을 포함합니다.
  • 빌드 데이터로 바이너리의 스탬프를 억제합니다 (--embed_* 옵션 참고).
  • 다른 모든 값은 기본값으로 유지됩니다.

별개의 임원을 선택하는 것이 바람직할 수 있는 이유는 여러 가지가 있습니다. 요청 구성에서 삭제합니다. 가장 중요한 사항:

첫째, 제거되고 최적화된 바이너리를 사용하면 툴이 차지하는 디스크 공간 및 분산 빌드의 네트워크 I/O 시간

둘째, 모든 빌드에서 exec 및 요청 구성을 분리함으로써 사소한 변경으로 인해 발생하는 비용이 많이 드는 재빌드를 피해야 합니다. 링커 옵션 변경과 같은 요청 구성 살펴봤습니다

올바른 증분 재빌드

Bazel 프로젝트의 주요 목표 중 하나는 올바른 성과 증분을 있습니다 이전 빌드 도구, 특히 Make 기반 빌드 도구는 가정을 하지 않는 경우가 많습니다.

첫째, 파일의 타임스탬프가 일정하게 증가합니다. 이는 일반적인 경우 이러한 가정에 매우 쉽게 어긋납니다. 동기화 중 파일의 이전 버전으로 인해 파일 수정 시간이 단축되는 경우 제조업체 기반 시스템은 다시 빌드되지 않습니다.

일반적으로 Make는 파일의 변경사항을 감지하지만 변경사항은 감지하지 않습니다. 살펴보겠습니다 지정된 빌드의 컴파일러에 전달된 옵션을 변경하는 경우 Make는 컴파일러를 다시 실행하지 않으며 make clean를 사용하여 이전 빌드의 잘못된 출력을 처리합니다.

또한 Make는 그 이후의 하위 프로세스가 출력 파일에 쓰기를 시작한 후에 시작됩니다. 동안 Make의 현재 실행이 실패하고 이후의 Make 호출은 잘린 출력 파일이 유효하다고 맹목적으로 가정합니다( 다시 빌드되지 않습니다. 마찬가지로 Make 프로세스가 종료하면 비슷한 상황이 발생할 수 있습니다

Bazel은 이러한 가정을 피합니다. Bazel은 모든 Google Cloud 프로젝트의 이미 수행된 작업을 수행했으며, 집합에서 발견된 빌드 단계에 대한 입력 파일 (및 타임스탬프) 및 컴파일 데이터베이스에 있는 명령어와 정확히 일치해야 하며, 데이터베이스 항목의 출력 파일 세트 (및 타임스탬프)가 정확히 일치 디스크에 있는 파일의 타임스탬프 입력 파일 또는 출력 변경사항 파일 또는 명령어 자체에 대한 액세스를 요청하는 경우 빌드 단계가 재실행됩니다.

올바른 증분 빌드 사용자가 얻을 수 있는 이점은 혼란을 야기할 수 있습니다. (또한 필요하든 선제적으로든 make clean 사용으로 인해 재빌드를 기다리는 데 소요되는 시간도 줄어듭니다.)

빌드 일관성 및 증분 빌드

공식적으로는 빌드 상태를 일관된 출력 파일이 존재하고 그 내용이 단계 또는 인증 절차에 명시된 대로 올바르다면 규칙을 만들어야 합니다 소스 파일을 수정하면 빌드가 일관되지 않은 것으로 간주되며 다음 실행까지 일관되지 않은 상태로 유지됩니다. 성공적으로 완료될 수 있습니다 Google에서는 이러한 상황을 불안정하다고 설명합니다. 비일관성 - 이는 일시적일 뿐이며 일관성은 복원해야 함 실행할 수 있습니다

안정적 빌드가 안정적이지 않은 일관되지 않은 상태에 도달하면 빌드 도구를 성공적으로 호출해도 일관성이 복원되지 않습니다. '멈춤' 상태이며 출력이 잘못된 상태로 유지됩니다. 안정적인 일관되지 않은 상태 Make (및 기타 빌드 도구) 사용자가 make clean를 입력하는 주된 이유입니다. 빌드 도구가 이러한 방식으로 실패했음을 확인한 후 시간이 오래 걸리고 매우 답답할 수 있습니다.

개념적으로 일관된 빌드를 달성하는 가장 간단한 방법은 모든 빌드를 클린 빌드로 만드세요. 이러한 접근 방식은 실용적이지만 시간이 너무 오래 걸리고, 빌드 도구가 유용하려면 일관성 저하 없이 증분 빌드를 수행할 수 있습니다.

위에서 설명한 것처럼 정확한 증분 종속성 분석은 어려운 일이며 다른 빌드 도구는 빌드됩니다 이에 반해 Bazel은 빌드 도구가 성공적으로 호출된 경우 일관된 상태가 됩니다 (소스 파일을 수정하는 동안 빌드 시 Bazel은 확인할 수 있습니다 하지만 이는 다음 빌드의 결과가 일관성 복원)

모든 보장과 마찬가지로 몇 가지 세부사항이 있습니다. 몇 가지 알려진 방법이 있습니다. Bazel과 일관되지 않은 안정된 상태가 되는 것을 방지할 수 있습니다 Google에서는 잠재적인 문제를 조사하고 증분 종속 항목 분석을 수행하지만 이를 조사하고 해결하기 위해 최선을 다할 것입니다. 정상 또는 "합리적"에서 발생하는 모든 안정적이고 일관되지 않은 상태 사용 빌드 도구가 있습니다.

Bazel에서 안정적으로 일관되지 않은 상태를 감지하면 버그를 신고하세요.

샌드박스 실행

Bazel은 샌드박스를 사용하여 작업이 밀폐되고 안전하게 실행되도록 있습니다. Bazel은 샌드박스에서 생성 (간단하게 말하자면 작업)을 실행합니다. 도구가 작업을 수행하는 데 필요한 최소한의 파일 집합만 포함합니다. 현재 샌드박스는 CONFIG_USER_NS 옵션이 있는 Linux 3.12 이상에서 작동합니다. macOS 10.11 이상에서도 지원됩니다.

시스템이 경보를 위한 샌드박스를 지원하지 않는 경우 Bazel에서 경고 표시 빌드가 밀폐되지 않을 수도 있고 호스트 시스템을 알 수 없는 방식으로 차단합니다. 이 경고를 비활성화하려면 Bazel에 --ignore_unsupported_sandboxing 플래그를 지정합니다.

Google Kubernetes와 같은 일부 플랫폼에서는 Debian 또는 사용자 네임스페이스는 보안상의 이유로 기본적으로 비활성화됩니다. 있습니다 이는 파일에서 /proc/sys/kernel/unprivileged_userns_clone: 속성이 존재하고 0이 포함된 경우, 사용자 네임스페이스를 활성화하여 sudo sysctl kernel.unprivileged_userns_clone=1

시스템 오류 때문에 Bazel 샌드박스가 규칙을 실행하지 못하는 경우가 설정할 수 있습니다 증상은 일반적으로 다음과 유사한 메시지를 출력하는 실패입니다. namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory 이 경우 다음 명령어를 사용하여 genrule에 대한 샌드박스를 비활성화하고 --strategy=Genrule=standalone--spawn_strategy=standalone 또한 Issue Tracker를 사용하고 사용 중인 Linux 배포판도 언급하여 문제를 조사하고 후속 버전에서 수정사항을 제공합니다.

빌드 단계

Bazel에서 빌드는 세 단계로 이루어집니다. 사용자로서 이들 간의 차이를 통해 빌드를 제어하는 옵션에 대한 통찰력을 얻을 수 있습니다. (아래 참고)

로드 단계

첫 번째 단계는 로드로, 이 단계에서는 초기 대상과 종속 항목의 전이적 클로저가 로드되고 파싱하고 평가 및 캐시합니다.

Bazel 서버가 시작된 후 첫 번째 빌드의 경우 로드 단계는 일반적으로 파일 시스템에서 많은 BUILD 파일이 로드되는 데 몇 초가 걸립니다. 포함 후속 빌드(특히 BUILD 파일이 변경되지 않은 경우) 매우 빠른 속도로 출동합니다.

이 단계에서 보고된 오류로는 패키지 없음, 대상을 찾을 수 없음, BUILD 파일의 어휘 및 문법 오류와 평가 오류 등

분석 단계

두 번째 단계인 분석은 빌드 종속 항목 그래프 생성, 빌드의 각 단계에서 수행해야 할 정확한 작업을 결정합니다.

로드와 마찬가지로 분석도 완전히 계산될 때 몇 초가 걸립니다. 그러나 Bazel은 한 빌드에서 다음 빌드로 종속 항목 그래프를 필요한 항목을 재분석하는 데, 이를 통해 증분 빌드를 이전 빌드 이후 패키지가 변경되지 않은 경우

이 단계에서 보고되는 오류는 부적절한 종속 항목, 잘못된 종속 항목 등입니다. 모든 규칙별 오류 메시지가 표시됩니다.

Bazel이 불필요한 파일을 사용하지 않으므로 로드 및 분석 단계가 빠릅니다. 이 단계에서는 작업을 결정하기 위해 BUILD 파일만 읽는 I/O입니다. 완료되었습니다. 이는 의도적으로 설계된 것으로 Bazel을 분석 도구의 좋은 토대가 되고, 예를 들어 Bazel의 query 명령어처럼 준비 단계입니다

실행 단계

빌드의 세 번째이자 마지막 단계는 실행입니다. 이 단계에서는 빌드의 각 단계의 출력이 입력과 일치하므로 컴파일/링크 등 필요에 따라 맞춤설정할 수 있습니다 이 단계에서는 빌드가 대규모 데이터의 경우 몇 초에서 한 시간 이상에 이르기까지, 대부분의 시간은 있습니다. 이 단계에서 보고되는 오류로는 소스 파일 누락, 오류 등이 있습니다. 특정 빌드 작업에 의해 실행된 도구에서 실행되는 경우, 출력됩니다.