LoginSignup
9
9

More than 5 years have passed since last update.

bazelでMacroを作成する

Posted at

version

henteko@~  $ bazel version
Build label: 0.1.1
Build target: bazel-out/local_darwin-fastbuild/bin/src/main/java/bazel-main_deploy.jar
Build time: Thu Oct 15 20:51:11 2015 (1444942271)
Build timestamp: 1444942271
Build timestamp as int: 1444942271

プロジェクト構成

今回のサンプルプロジェクトです
以下がプロジェクト構成です
Macroを作成するだけなのでシンプルにしました

henteko@~/Desktop/dev/sample  $ tree
.
├── BUILD
├── WORKSPACE
├── android.apk
└── deploygate.bzl

0 directories, 4 files

Macroを作成する

基本はBazel公式のドキュメントに書いてあります

今回作成するMacroは、ローカルにあるapkをDeployGateにアップロードするようなMacroです
最終的にはBUILDファイルに以下のように書くことで、Macroを実行できるようにします

load("deploygate", "deploygate")
deploygate(
  name = "deploy",
  user_name = "your_deploygate_name",
  api_key = "your_deploygate_api_key",
  apk = "android.apk"
)
$ bazel build //:deploy

deploygate.bzlの作成

bazelのMacroでは.bzlファイルを作成して、各Macroごとの引数の指定や実際の処理を書きます

処理の記述

実際の処理は以下のように書きます

def _impl(ctx):
  out = ctx.outputs.result
  apk = ctx.file.apk
  name = ctx.attr.user_name
  api_key = ctx.attr.api_key
  ctx.action(
    outputs = [out],
    inputs = [apk],
    command = "curl -F 'file=@%s' -F 'token=%s' -F 'message=sample' https://deploygate.com/api/users/%s/apps > %s" % (apk.path, api_key, name, out.path),
  )

処理の記述にはPaythonに似たbazel独自言語を使って記述します
ctx.fileやctx.attrにはMacroの引数指定で指定した文字列などが渡ってきます
今回はDeployGateにcurlを使ってapkをアップロードするためにcurlを実行するようにしてます
ctx.actionはコマンドをそのまま実行することができるんですが、outputsファイルを指定しなければいけないので、curlで得た文字列(deploygateの場合はjson)をそのままoutputsとして吐き出すようにしてます

Macroの引数指定

Macroの引数指定にはrule関数を使います
これがMacro自身のインターフェースを表します

deploygate = rule(
  implementation=_impl,
  attrs={
    "user_name": attr.string(mandatory=True),
    "api_key": attr.string(mandatory=True),
    "apk": attr.label(mandatory=True, allow_files=True, single_file=True),
  },
  outputs = {"result": "%{name}_result.txt"},
)

これだとuser_name, api_key, apkが引数指定されています
また、mandatory=Trueにしているとこの引数は必須となり、引数として足らないと実行時にエラーになって怒ってくれます、便利
attrにはstringやlabel以外にも色々な型があるので、詳しくは公式ドキュメントを参照してください

これでMacroの作成は終了です
あとは BUILDファイルに上で説明したように記述すると、deployビルドを実行することができます

deploygate.bzlの全体

deploygate.bzl
def _impl(ctx):
  out = ctx.outputs.result
  apk = ctx.file.apk
  name = ctx.attr.user_name
  api_key = ctx.attr.api_key
  ctx.action(
    outputs = [out],
    inputs = [apk],
    command = "curl -F 'file=@%s' -F 'token=%s' -F 'message=sample' https://deploygate.com/api/users/%s/apps > %s" % (apk.path, api_key, name, out.path),
  )

deploygate = rule(
  implementation=_impl,
  attrs={
    "user_name": attr.string(mandatory=True),
    "api_key": attr.string(mandatory=True),
    "apk": attr.label(mandatory=True, allow_files=True, single_file=True),
  },
  outputs = {"result": "%{name}_result.txt"},
)

さいごに

今回bazel周りを触ってみた感想としては、 Androidをビルドするにしてもまだまだ環境が整ってなくて結構苦労するなという印象でした
ただ、Macroの作成などは比較的簡単に行えそうな感じがしました
それと、buildでは何もdiffがないとそもそも実行されないので、余分なCPUリソースを使わなくてすんで親切な気がします
来年のAndroidStudio統合が待ち遠しいですね

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9