1*bcb5dc79SHONG Yifan# Copyright 2019 The Bazel Authors. All rights reserved. 2*bcb5dc79SHONG Yifan# 3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License"); 4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License. 5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at 6*bcb5dc79SHONG Yifan# 7*bcb5dc79SHONG Yifan# http://www.apache.org/licenses/LICENSE-2.0 8*bcb5dc79SHONG Yifan# 9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software 10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS, 11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and 13*bcb5dc79SHONG Yifan# limitations under the License. 14*bcb5dc79SHONG Yifan 15*bcb5dc79SHONG Yifan""" 16*bcb5dc79SHONG Yifanrun_binary() build rule implementation. 17*bcb5dc79SHONG Yifan 18*bcb5dc79SHONG YifanRuns a binary as a build action. This rule does not require Bash (unlike native.genrule()). 19*bcb5dc79SHONG Yifan""" 20*bcb5dc79SHONG Yifan 21*bcb5dc79SHONG Yifanload("//lib:dicts.bzl", "dicts") 22*bcb5dc79SHONG Yifan 23*bcb5dc79SHONG Yifandef _run_binary_impl(ctx): 24*bcb5dc79SHONG Yifan tool_as_list = [ctx.attr.tool] 25*bcb5dc79SHONG Yifan args = [ 26*bcb5dc79SHONG Yifan # Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in args. 27*bcb5dc79SHONG Yifan # 28*bcb5dc79SHONG Yifan # To keep the rule simple, do not expand Make Variables (like *_binary.args usually would). 29*bcb5dc79SHONG Yifan # (We can add this feature later if users ask for it.) 30*bcb5dc79SHONG Yifan # 31*bcb5dc79SHONG Yifan # Also for simple implementation and usage, do not Bash-tokenize the arguments. Without 32*bcb5dc79SHONG Yifan # tokenization the user can write args=["a b"] to pass (a b) as one argument, but with 33*bcb5dc79SHONG Yifan # tokenization they would have to write args=["'a b'"] or args=["a\\ b"]. There's no 34*bcb5dc79SHONG Yifan # documented tokenization function anyway (as of 2019-05-21 ctx.tokenize exists but is 35*bcb5dc79SHONG Yifan # undocumented, see https://github.com/bazelbuild/bazel/issues/8389). 36*bcb5dc79SHONG Yifan ctx.expand_location(a, tool_as_list) 37*bcb5dc79SHONG Yifan for a in ctx.attr.args 38*bcb5dc79SHONG Yifan ] 39*bcb5dc79SHONG Yifan envs = { 40*bcb5dc79SHONG Yifan # Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in the values. 41*bcb5dc79SHONG Yifan k: ctx.expand_location(v, tool_as_list) 42*bcb5dc79SHONG Yifan for k, v in ctx.attr.env.items() 43*bcb5dc79SHONG Yifan } 44*bcb5dc79SHONG Yifan ctx.actions.run( 45*bcb5dc79SHONG Yifan outputs = ctx.outputs.outs, 46*bcb5dc79SHONG Yifan inputs = ctx.files.srcs, 47*bcb5dc79SHONG Yifan tools = [ctx.executable.tool], 48*bcb5dc79SHONG Yifan executable = ctx.executable.tool, 49*bcb5dc79SHONG Yifan arguments = args, 50*bcb5dc79SHONG Yifan mnemonic = "RunBinary", 51*bcb5dc79SHONG Yifan use_default_shell_env = False, 52*bcb5dc79SHONG Yifan env = dicts.add(ctx.configuration.default_shell_env, envs), 53*bcb5dc79SHONG Yifan ) 54*bcb5dc79SHONG Yifan return DefaultInfo( 55*bcb5dc79SHONG Yifan files = depset(ctx.outputs.outs), 56*bcb5dc79SHONG Yifan runfiles = ctx.runfiles(files = ctx.outputs.outs), 57*bcb5dc79SHONG Yifan ) 58*bcb5dc79SHONG Yifan 59*bcb5dc79SHONG Yifanrun_binary = rule( 60*bcb5dc79SHONG Yifan implementation = _run_binary_impl, 61*bcb5dc79SHONG Yifan doc = "Runs a binary as a build action.\n\nThis rule does not require Bash (unlike" + 62*bcb5dc79SHONG Yifan " `native.genrule`).", 63*bcb5dc79SHONG Yifan attrs = { 64*bcb5dc79SHONG Yifan "tool": attr.label( 65*bcb5dc79SHONG Yifan doc = "The tool to run in the action.\n\nMust be the label of a *_binary rule," + 66*bcb5dc79SHONG Yifan " of a rule that generates an executable file, or of a file that can be" + 67*bcb5dc79SHONG Yifan " executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary" + 68*bcb5dc79SHONG Yifan " with executable permission on Linux). This label is available for" + 69*bcb5dc79SHONG Yifan " `$(execpath)` and `$(location)` expansion in `args` and `env`.", 70*bcb5dc79SHONG Yifan executable = True, 71*bcb5dc79SHONG Yifan allow_files = True, 72*bcb5dc79SHONG Yifan mandatory = True, 73*bcb5dc79SHONG Yifan cfg = "exec", 74*bcb5dc79SHONG Yifan ), 75*bcb5dc79SHONG Yifan "env": attr.string_dict( 76*bcb5dc79SHONG Yifan doc = "Environment variables of the action.\n\nSubject to " + 77*bcb5dc79SHONG Yifan " [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" + 78*bcb5dc79SHONG Yifan " expansion.", 79*bcb5dc79SHONG Yifan ), 80*bcb5dc79SHONG Yifan "srcs": attr.label_list( 81*bcb5dc79SHONG Yifan allow_files = True, 82*bcb5dc79SHONG Yifan doc = "Additional inputs of the action.\n\nThese labels are available for" + 83*bcb5dc79SHONG Yifan " `$(execpath)` and `$(location)` expansion in `args` and `env`.", 84*bcb5dc79SHONG Yifan ), 85*bcb5dc79SHONG Yifan "outs": attr.output_list( 86*bcb5dc79SHONG Yifan mandatory = True, 87*bcb5dc79SHONG Yifan doc = "Output files generated by the action.\n\nThese labels are available for" + 88*bcb5dc79SHONG Yifan " `$(execpath)` and `$(location)` expansion in `args` and `env`.", 89*bcb5dc79SHONG Yifan ), 90*bcb5dc79SHONG Yifan "args": attr.string_list( 91*bcb5dc79SHONG Yifan doc = "Command line arguments of the binary.\n\nSubject to" + 92*bcb5dc79SHONG Yifan " [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" + 93*bcb5dc79SHONG Yifan " expansion.", 94*bcb5dc79SHONG Yifan ), 95*bcb5dc79SHONG Yifan }, 96*bcb5dc79SHONG Yifan) 97