除了公共部分BUILD文件可以使用的规则外,还有一些与语言相关的build rule。
这里根据不同的语言,来写整理。
Java
Bin rules
java_binary
java_binary(name, deps, srcs, data, resources, args, classpath_resources, compatible_with, create_executable, deploy_manifest_lines, deprecation, distribs, features, javacopts, jvm_flags, launcher, licenses, main_class, output_licenses, plugins, resource_jars, resource_strip_prefix, restricted_to, runtime_deps, stamp, tags, testonly, toolchains, use_testrunner, visibility)
build一个java的jar文件,并且套上一个shell的脚本来辅助运行。隐式的输出target:
name.jar
name-src.jar
name_deploy.jar:这个比较特殊,必须显式的build才会生成,比如 bazel build //package:target_deploy.jar
name_deploy-src.jar
Lib rules
java_import
java_import(name, deps, data, compatible_with, constraints, deprecation, distribs, exports, features, jars, licenses, neverlink, proguard_specs, restricted_to, runtime_deps, srcjar, tags, testonly, visibility)
这个rule允许使用预编译好的.jar文件当做lib,来提供给java_library和java_binary规则用。
java_library
java_library(name, deps, srcs, data, resources, compatible_with, deprecation, distribs, exported_plugins, exports, features, javacopts, licenses, neverlink, plugins, proguard_specs, resource_jars, resource_strip_prefix, restricted_to, runtime_deps, tags, testonly, visibility)
这个rule编译和链接源码到.jar包中。隐式输出目标:
libname.jar
libname-src.jar
属性参数介绍:
- name:本rule的唯一标识
- deps:编译阶段的依赖
- srcs:源码文件列表,如果java文件时生成的那么放入生成java文件的target label
- exports:称为输出的libs,也就是说这里面定义的libs可以被依赖此rule的父rule所使用。
- javacopts:全局编译选项之后的此target的额外编译选项,会在全局选项之后传给javac
- neverlink:Boolean类型,默认0,如果此target的libary只是在编译阶段使用不会再运行阶段使用,那么就需要设置为True
- resource_jars:设置包含Java源码的包,将会添加到输出jar中
这里重点讲下exports和dep的区别和联系。rule X可以访问code Y只要X与Y之间有一个deps边以及0个或多个exports边。接下来再看一个更清楚的例子,假设A依赖于B,B依赖于C,在这种情况下C如果发生改变,那么在build A时重新build所有。但是此时的A并不能访问C中的class,除非让A有个直接的deps到C,或者让B exports C;显然后者操作更为轻松尤其是当有很多C时。还剩下两个重点:
1、exports可以传递;
2、exports和deps不冲突,根据需要可以将一个target既加在deps里又加在exports中
Python
Bin rules
py_binary
py_binary(name, deps, srcs, data, args, compatible_with, default_python_version, deprecation, distribs, features, imports, legacy_create_init, licenses, main, output_licenses, restricted_to, srcs_version, stamp, tags, testonly, toolchains, visibility)
这个rule是一个可执行的Python程序,包含了一些Python源码,一个*.runfiles的目录树内含了所有运行时所需的代码和数据,以及一个配置了初始化环境和数据的启动脚本。在py_binary中可以依赖别的py_library
py_binary( name = "foo", srcs = ["foo.py"], data = [":transform"], # a cc_binary which we invoke at run time deps = [ "//pyglib", ":foolib", # a py_library ], )
在别的非Python的bin中如果想运行py_binary那么可以放入data属性中:
py_binary( name = "test_main", srcs = ["test_main.py"], deps = [":testlib"], ) java_library( name = "testing", srcs = glob(["*.java"]), data = [":test_main"] )
Lib rules
py_library
py_library(name, deps, srcs, data, compatible_with, deprecation, distribs, features, imports, licenses, restricted_to, srcs_version, tags, testonly, visibility)
- name:唯一名字
- deps:List of labels; optional依赖,可以是源码但是为了方便阅读还是放在srcs里好
- srcs:List of labels; optional包含生成目标的源码
- data:List of strings; optional运行时所需的文件
- imports:List of strings; optional要加载的路径,加到PYTHONPATH中
- srcs_version:String; optional; default is “PY2AND3″只是为了文档的目的,不会影响python解释器的版本。
一般通用
filegroup
filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, output_licenses, path, restricted_to, tags, testonly, visibility)
使用这个可以得到一个目标的合集名字,方便在其他rule中引用。举例:
filegroup( name = "mygroup", srcs = [ "a_file.txt", "some/subdirectory/another_file.txt", ], )
filegroup( name = "exported_testdata", srcs = glob([ "testdata/*.dat", "testdata/logs/**/*.log", ]), )
cc_library( name = "my_library", srcs = ["foo.cc"], data = [ "//my_package:exported_testdata", "//my_package:mygroup", ], )
genrule
genrule(name, srcs, outs, cmd, compatible_with, deprecation, distribs, executable, features, licenses, local, message, output_licenses, output_to_bindir, restricted_to, tags, testonly, tools, visibility)
这个rule的功能是使用用户定义的Bash命令产生一个或多个文件。当没有特定的rule来完成某个任务时,就可以使用这个通用的build rule。使用建议:
- 输出应该是确定和封闭的。每次运行不会反生变化
- 广泛使用$(location),来获取文件位置
- 写common Skylark宏代码
- 确保推出代码可以正确只是genrule的成功或失败
- 不要写print,一个成功的genrule应该是无打印的
- $$表示$,为了避免和shell命令冲突,ls $(dirname $x)应写成ls $$(dirname $$x)。
- 避免在genrule中创建软连接以及文件夹。因为Bazel不会复制和检查这些。
- 引用genrule的时候,可以使用genrule的label或者每个genrule输出的label。这两种方法根据实际需要来。
下面这个例子是调用perl脚本来产生一个foo.h文件。
genrule( name = "foo", srcs = [], outs = ["foo.h"], cmd = "./$(location create_foo.pl) > \"$@\"", tools = ["create_foo.pl"], )
接下来的例子是使用filegroup和另一个genrule产生的文件作为src:
genrule( name = "concat_all_files", srcs = [ "//some:files", # a filegroup with multiple files in it ==> $(locations) "//other:gen", # a genrule with a single output ==> $(location) ], outs = ["concatenated.txt"], cmd = "cat $(locations //some:files) $(location //other:gen) > $@", )
参数介绍:
- name:唯一名字
- srcs:List of labels; optional源输入文件
- outs:List of filenames; required; nonconfigurable输出文件列表,文件处于package内可以被label索引到。
- cmd:String; required运行的cmd
-
- 可以使用$(location)。
- outs中的文件名不包括在替换中,在cmd中需要以$(@D), $@, $(OUTS) or $(location output_name)方式出现。
- 有了host配置后,环境变量共享库是可在cmd中用的。比如$(JAVA), $(JAVAC) and $(JAVABASE)。
- 如果cmd执行后的返回值不是0那么就认为失败了。executable:Boolean; optional; nonconfigurable; default is 0指示输出文件是否是可执行的。
tools:List of labels; optional表示rule依赖的tool,可以是已有的文件,也可以是一个target或者生成的文件。
转载需保留链接来源:软件玩家 » Bazel编写BUILD文件