소개
Bazel을 처음 사용하시나요? 잘 찾아오셨습니다. Bazel 사용에 대한 간단한 소개는 이 첫 번째 빌드 튜토리얼을 따르세요. 이 튜토리얼에서는 Bazel의 컨텍스트에서 사용되는 주요 용어를 정의하고 Bazel 워크플로의 기본사항을 안내합니다. 필요한 도구부터 시작하여 복잡성이 증가하는 세 가지 프로젝트를 빌드하고 실행하며 복잡성이 증가하는 방법과 이유를 알아봅니다.
Bazel은 다국어 빌드를 지원하는 빌드 시스템이지만 이 튜토리얼에서는 C++ 프로젝트를 예로 사용하고 대부분의 언어에 적용되는 일반적인 가이드라인과 흐름을 제공합니다.
예상 완료 시간: 30분
기본 요건
아직 Bazel을 설치하지 않았다면 먼저 Bazel을 설치하세요. 이 튜토리얼에서는 소스 제어를 위해 Git을 사용하므로 최상의 결과를 얻으려면 Git 도 설치하세요.
다음으로 선택한 명령줄 도구에서 다음을 실행하여 Bazel의 GitHub 저장소에서 샘플 프로젝트를 가져옵니다.
git clone https://github.com/bazelbuild/examples이 튜토리얼의 샘플 프로젝트는 examples/cpp-tutorial 디렉터리에 있습니다.
구조를 살펴보세요.
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── MODULE.bazel
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
세 가지 파일 세트가 있으며 각 세트는 이 튜토리얼의 단계를 나타냅니다. 첫 번째 단계에서는 단일 타겟이 단일 패키지에 있는 것을 빌드합니다. 두 번째 단계에서는 단일 패키지에서 바이너리와 라이브러리를 모두 빌드합니다. 세 번째이자 마지막 단계에서는 여러 패키지가 있는 프로젝트를 빌드하고 여러 타겟으로 빌드합니다.
요약: 소개
Bazel (및 Git)을 설치하고 이 튜토리얼의 저장소를 클론하여 Bazel을 사용한 첫 번째 빌드의 토대를 마련했습니다. 다음 섹션으로 이동하여 몇 가지 용어를 정의하고 작업공간을 설정합니다.
시작하기
프로젝트를 빌드하려면 먼저 작업공간을 설정해야 합니다. 작업공간은 프로젝트의 소스 파일과 Bazel의 빌드 출력을 보유하는 디렉터리입니다. 또한 다음과 같은 중요한 파일이 포함되어 있습니다.
- 디렉터리와 그 콘텐츠를 Bazel 작업공간으로 식별하고 프로젝트 디렉터리 구조의 루트에 있는
MODULE.bazel파일. 외부 종속 항목을 지정하는 위치이기도 합니다. - 프로젝트의 여러 부분을 빌드하는 방법을 Bazel에 알려주는 하나 이상의
BUILD파일. 작업공간 내의 디렉터리는BUILD파일이 포함된 패키지입니다. (패키지에 관한 자세한 내용은 이 튜토리얼의 뒷부분에서 설명합니다.)
향후 프로젝트에서 디렉터리를 Bazel 작업공간으로 지정하려면 해당 디렉터리에 MODULE.bazel이라는 빈 파일을 만듭니다. 이 튜토리얼의 목적을 위해 각 단계에 MODULE.bazel 파일이 이미 있습니다.
BUILD 파일 이해
BUILD 파일에는 Bazel을 위한 여러 가지 유형의 안내가 포함되어 있습니다. 각
BUILD 파일에는 실행 가능한 바이너리
또는 라이브러리와 같이 원하는 출력을 빌드하는 방법을 Bazel에 알려주는 안내 세트인
규칙이 하나 이상 필요합니다. BUILD 파일에 있는 빌드 규칙의 각 인스턴스를
타겟이라고 하며 특정
소스 파일 및
종속 항목 세트를 가리킵니다. 타겟은 다른 타겟을 가리킬 수도 있습니다.
cpp-tutorial/stage1/main 디렉터리의 BUILD 파일을 살펴보세요.
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
이 예에서 hello-world 타겟은 Bazel의 기본 제공
cc_binary 규칙을 인스턴스화합니다. 이 규칙은 종속 항목이 없는 hello-world.cc> 소스 파일에서 자체 포함 실행 가능한 바이너리를 빌드하도록 Bazel에 지시합니다.
요약: 시작하기
이제 몇 가지 주요 용어와 이 프로젝트 및 Bazel 전반의 컨텍스트에서 이러한 용어가 의미하는 바를 알게 되었습니다. 다음 섹션에서는 프로젝트의 1단계를 빌드하고 테스트합니다.
1단계: 단일 타겟, 단일 패키지
프로젝트의 첫 번째 부분을 빌드할 시간입니다. 시각적 참조를 위해 프로젝트의 1단계 섹션 구조는 다음과 같습니다.
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── MODULE.bazel
다음을 실행하여 cpp-tutorial/stage1 디렉터리로 이동합니다.
cd cpp-tutorial/stage1다음을 실행합니다.
bazel build //main:hello-world타겟 라벨에서 //main: 부분은 작업공간의 루트를 기준으로 하는 BUILD 파일의 위치이고 hello-world는 BUILD 파일의 타겟 이름입니다.
Bazel은 다음과 같은 항목을 생성합니다.
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
첫 번째 Bazel 타겟을 빌드했습니다. Bazel은 작업공간의 루트에 있는 bazel-bin 디렉터리에 빌드 출력을 배치합니다.
이제 새로 빌드된 바이너리를 테스트합니다. 바이너리는 다음과 같습니다.
bazel-bin/main/hello-world그러면 "Hello world" 메시지가 출력됩니다.
다음은 1단계의 종속 항목 그래프입니다.

요약: 1단계
첫 번째 빌드를 완료했으므로 빌드의 구조를 대략적으로 파악할 수 있습니다. 다음 단계에서는 다른 타겟을 추가하여 복잡성을 더합니다.
2단계: 여러 빌드 타겟
단일 타겟은 소규모 프로젝트에 충분하지만 대규모 프로젝트를 여러 타겟과 패키지로 분할하는 것이 좋습니다. 이렇게 하면 빠른 증분 빌드(즉, Bazel은 변경된 항목만 다시 빌드함)가 가능하고 프로젝트의 여러 부분을 한 번에 빌드하여 빌드 속도를 높일 수 있습니다. 이 튜토리얼의 이 단계에서는 타겟을 추가하고 다음 단계에서는 패키지를 추가합니다.
2단계에서 작업하는 디렉터리는 다음과 같습니다.
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
cpp-tutorial/stage2/main 디렉터리의 BUILD 파일을 살펴보세요.
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
이 BUILD 파일을 사용하면 Bazel은 먼저 hello-greet 라이브러리 (Bazel의 기본 제공 cc_library
규칙 사용)를 빌드한 다음
hello-world 바이너리를 빌드합니다. hello-world 타겟의 deps 속성은 hello-world 바이너리를 빌드하는 데 hello-greet 라이브러리가 필요하다고 Bazel에 알려줍니다.
이 새 버전의 프로젝트를 빌드하려면 먼저 디렉터리를 변경해야 합니다. 다음을 실행하여 cpp-tutorial/stage2 디렉터리로 전환합니다.
cd ../stage2이제 다음과 같은 익숙한 명령어를 사용하여 새 바이너리를 빌드할 수 있습니다.
bazel build //main:hello-worldBazel은 다음과 같은 항목을 다시 생성합니다.
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
이제 새로 빌드된 바이너리를 테스트할 수 있습니다. 그러면 다른 "Hello
world"가 반환됩니다.
bazel-bin/main/hello-world이제 hello-greet.cc를 수정하고 프로젝트를 다시 빌드하면 Bazel은 해당 파일만 다시 컴파일합니다.
종속 항목 그래프를 보면 hello-world가 hello-greet라는 추가 입력에 종속되어 있음을 알 수 있습니다.

요약: 2단계
이제 두 개의 타겟으로 프로젝트를 빌드했습니다. hello-world 타겟은 하나의 소스 파일을 빌드하고 두 개의 추가 소스 파일을 빌드하는 다른 타겟 (//main:hello-greet)에 종속됩니다. 다음 섹션에서는 한 단계 더 나아가 다른 패키지를 추가합니다.
3단계: 여러 패키지
이 다음 단계에서는 복잡성을 더하고 여러 패키지로 프로젝트를 빌드합니다. cpp-tutorial/stage3 디렉터리의 구조와 콘텐츠를 살펴보세요.
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
이제 두 개의 하위 디렉터리가 있으며 각 디렉터리에는 BUILD 파일이 포함되어 있습니다. 따라서 Bazel의 경우 작업공간에 이제 lib와 main이라는 두 개의 패키지가 포함되어 있습니다.
lib/BUILD 파일을 살펴보세요.
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
main/BUILD 파일을 살펴보세요.
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
기본 패키지의 hello-world 타겟은 lib 패키지의 hello-time 타겟
에 종속됩니다 (따라서 타겟 라벨 //lib:hello-time). Bazel은 deps 속성을 통해 이를 알고 있습니다. 종속 항목 그래프에 반영된 것을 확인할 수 있습니다.

빌드가 성공하려면 공개 상태 속성을 사용하여 lib/BUILD의 //lib:hello-time 타겟을 main/BUILD의 타겟에 명시적으로 표시해야 합니다.
기본적으로 타겟은 동일한 BUILD 파일의 다른 타겟에만 표시되기 때문입니다. Bazel은 타겟 공개 상태를 사용하여 구현 세부정보가 포함된 라이브러리가 공개 API로 유출되는 등의 문제를 방지합니다.
이제 이 최종 버전의 프로젝트를 빌드합니다. 다음을 실행하여 cpp-tutorial/stage3 디렉터리로 전환합니다.
cd ../stage3다시 다음 명령어를 실행합니다.
bazel build //main:hello-worldBazel은 다음과 같은 항목을 생성합니다.
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
이제 이 튜토리얼의 마지막 바이너리를 테스트하여 최종 Hello world 메시지를 확인합니다.
bazel-bin/main/hello-world요약: 3단계
이제 세 개의 타겟이 있는 두 개의 패키지로 프로젝트를 빌드하고 패키지 간의 종속 항목을 이해했으므로 Bazel을 사용하여 향후 프로젝트를 빌드할 수 있습니다. 다음 섹션에서는 Bazel 여정을 계속하는 방법을 살펴보세요.
다음 단계
이제 Bazel을 사용하여 첫 번째 기본 빌드를 완료했지만 이는 시작에 불과합니다. 다음은 Bazel을 사용하여 계속 학습할 수 있는 추가 리소스입니다.
- C++에 계속 집중하려면 일반적인 C++ 빌드 사용 사례를 읽어보세요.
- Bazel을 사용하여 다른 애플리케이션 빌드를 시작하려면 튜토리얼에서 Java, Android 애플리케이션 또는 iOS 애플리케이션을 참고하세요.
- 로컬 및 원격 저장소 작업에 관해 자세히 알아보려면 외부 종속 항목을 읽어보세요.
- Bazel의 다른 규칙에 관해 자세히 알아보려면 이 참조 가이드를 참고하세요.
즐거운 빌드 되세요!