개요
이번 게시글에서는 StarLark
언어를 사용해 md5 파일 생성하는 예제를 구현한다. 본 예제를 통해 사용자 정의 rule를 만들고, rule 기능을 수행하는 implementation function를 구현한다.
풀어야 할 과제
다음과 같은 파일로 구성된다. main.cc
파일의 md5 해쉬값을 생성할 것이다.
.bazelrc
BUILD.bazel
main.cc
make_md5_binary.bzl
MODULE.bazel
console 창에 아래 명령어를 입력하면 윈도우 환경에서 해쉬값을 얻어낼 수 있다.
[윈도우] certutil -hashfile main.cc md5
[윈도우] bash.exe -c "md5sum main.cc"
[우분투] md5sum main.cc
결과 화면
CMD> certutil -hashfile main.cc md5
MD5의 main.cc 해시:
5de1159032af460be82d283fbbcea820
CertUtil: -hashfile 명령이 성공적으로 완료되었습니다.
CMD> bash.exe -c "md5sum main.cc"
5de1159032af460be82d283fbbcea820 main.cc
.bazelrc
모든 명령어를 처리하는 과정에서 bzlmod
기반 옵션이 추가되도록 다음 문구를 입력해준다.
common --enable_bzlmod
MODULE.bazel
MODULE.bazel
파일은 빌드 시스템의 맨 상위를 추적하는 용도로만 사용할 예정임으로 파일만 생성하고 추가할 내용은 없다.
make_md5_binary.bzl
오늘 게시글에서 가장 중요한 파트는 아래 코딩을 이해하는 것이다. .bzl
확장자는 StarLark 언어로 rule 또는 aspect를 정의할 수 있다.
아래 코딩은 make_md5_binary
rule를 정의한다. 전체적인 흐름은 BUILD.bazel
에서 make_md5_binary
를 사용하고, 컴파일 과정에서 분석이 시작되면, 먼저 아래 쪽 rule 구문이 수행하는데, implementation
항목으로 rule 구문 이후에 호출할 implementation function를 지정한다. 부가적으로 필요한 항목을 attrs
항목으로 추가한다.
이렇게 작동된 결과는 묶어 현재 분석중인 rule의 context object
를 생성 한 후, context object
의 implementation function로 ctx
이름으로 자기 자신을 전달해 수행한다. implementation function는 필히 dependency set
를 반환해야 한다.
ctx
는 ctx.actions
항목으로 각종 필요한 함수를 제공한다.ctx.attr
의 세부 항목으로 rule에서 정의한 attrs
의 세부 항목을 맵핑하고, 자주 사용하는 항목에 대한 축약 attribute를 정의하고 있다.
ctx.outputs
항목은 rule의 attrs에서 attr.ouput()
으로 생성된 이름에 대한 축약 attribute다. 따라서 ctx.outputs.out
는 rule의 "out"
이 적용된 값이다.ctx.file
항목은 rule의 attrs에서 attr.label
에서 allow_single_file = True
항목을 가진 이름에 대한 축약 attribute다. 따라서 ctx.file.src
는 rule의 "src"
이 적용된 적용된 값이다.
ctx.actions.run_shell
구문은 bash.exe
를 수행한다.outputs
항목은 출력으로 사용할 File
객체 목록을, inputs
항목은 입력으로 사용할 File
객체 목록을, 각각 의미하고, command
는 bash.exe -c
이후에 추가할 제어 명령어를 정의한다. format
함수를 통해 해시할 파일 이름을 적어주고 redirection >
를 통해 저장할 파일 이름을 적어주면 원하는 결과를 얻어낼 수 있다.
마지막으로 implementation function는 의존성 파일 정보를 반환한다.
최종적으로 만들어진 md5 파일을 누군가 사용하길 원할 것이다.
# make_md5_binary.bzl
def _make_md5_binary_impl(ctx):
ctx.actions.run_shell(
outputs = [ctx.outputs.out],
inputs = [ctx.file.src],
command = "md5sum {} > {}".format(ctx.file.src.path, ctx.outputs.out.path),
)
return DefaultInfo(files = depset([ctx.outputs.out]))
make_md5_binary = rule(
implementation = _make_md5_binary_impl,
attrs = {
"src": attr.label(mandatory = True, allow_single_file = True),
"out": attr.output(),
},
)
참고로 visual code에 Bazel-Stack-VSCode 플러그인을 설치하면 조금 더 깔금한 환경에서 코딩을 작성할 수 있다.
BUILD.bazel
load
함수로 bzl
파일을 로드하고 make_md5_binary
rule를 사용할 수 있도록 가져온다. make_md5_binary
사용 과정에서 항목 이름과 bzl
파일 적성 파일과 서로 맵핑되는 것을 알 수 있다.
load(":make_md5_binary.bzl","make_md5_binary")
make_md5_binary(
name ="test",
src = "main.cc",
out ="test.md5"
)
실행하기
CMD> bazelisk build //...
INFO: Analyzed target //:test (4 packages loaded, 7 targets configured).
INFO: Found 1 target...
Target //:test up-to-date:
bazel-bin/test.md5
INFO: Elapsed time: 5.757s, Critical Path: 5.23s
INFO: 2 processes: 1 internal, 1 local.
INFO: Build completed successfully, 2 total actions
CMD> bash.exe -c "cat bazel-bin/test.md5"
5de1159032af460be82d283fbbcea820 main.cc
예제 파일
'building system > bazel' 카테고리의 다른 글
platforms module 사용하기 (0) | 2024.01.29 |
---|---|
dependency attribute란? (0) | 2024.01.27 |
NASM으로 asm 파일을 컴파일해 사용하는 bazel 빌드 예제 (0) | 2024.01.24 |
bzlMod 기반 GoogleTest 기본 예제 구현하기 (1) | 2024.01.23 |
새로운 의존성 설계 bzlMod 기본 예제 구현하기 (1) | 2024.01.22 |