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"""native_binary() and native_test() rule implementations. 16*bcb5dc79SHONG Yifan 17*bcb5dc79SHONG YifanThese rules let you wrap a pre-built binary or script in a conventional binary 18*bcb5dc79SHONG Yifanand test rule respectively. They fulfill the same goal as sh_binary and sh_test 19*bcb5dc79SHONG Yifando, but they run the wrapped binary directly, instead of through Bash, so they 20*bcb5dc79SHONG Yifandon't depend on Bash and work with --shell_executable="". 21*bcb5dc79SHONG Yifan""" 22*bcb5dc79SHONG Yifan 23*bcb5dc79SHONG Yifandef _impl_rule(ctx): 24*bcb5dc79SHONG Yifan out = ctx.actions.declare_file(ctx.attr.out if (ctx.attr.out != "") else ctx.attr.name + ".exe") 25*bcb5dc79SHONG Yifan ctx.actions.symlink( 26*bcb5dc79SHONG Yifan target_file = ctx.executable.src, 27*bcb5dc79SHONG Yifan output = out, 28*bcb5dc79SHONG Yifan is_executable = True, 29*bcb5dc79SHONG Yifan ) 30*bcb5dc79SHONG Yifan runfiles = ctx.runfiles(files = ctx.files.data) 31*bcb5dc79SHONG Yifan 32*bcb5dc79SHONG Yifan # Bazel 4.x LTS does not support `merge_all`. 33*bcb5dc79SHONG Yifan # TODO: remove `merge` branch once we drop support for Bazel 4.x. 34*bcb5dc79SHONG Yifan if hasattr(runfiles, "merge_all"): 35*bcb5dc79SHONG Yifan runfiles = runfiles.merge_all([ 36*bcb5dc79SHONG Yifan d[DefaultInfo].default_runfiles 37*bcb5dc79SHONG Yifan for d in ctx.attr.data + [ctx.attr.src] 38*bcb5dc79SHONG Yifan ]) 39*bcb5dc79SHONG Yifan else: 40*bcb5dc79SHONG Yifan for d in ctx.attr.data: 41*bcb5dc79SHONG Yifan runfiles = runfiles.merge(d[DefaultInfo].default_runfiles) 42*bcb5dc79SHONG Yifan runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles) 43*bcb5dc79SHONG Yifan 44*bcb5dc79SHONG Yifan return DefaultInfo( 45*bcb5dc79SHONG Yifan executable = out, 46*bcb5dc79SHONG Yifan files = depset([out]), 47*bcb5dc79SHONG Yifan runfiles = runfiles, 48*bcb5dc79SHONG Yifan ) 49*bcb5dc79SHONG Yifan 50*bcb5dc79SHONG Yifan_ATTRS = { 51*bcb5dc79SHONG Yifan "src": attr.label( 52*bcb5dc79SHONG Yifan executable = True, 53*bcb5dc79SHONG Yifan # This must be used instead of `allow_single_file` because otherwise a 54*bcb5dc79SHONG Yifan # target with multiple default outputs (e.g. py_binary) would not be 55*bcb5dc79SHONG Yifan # allowed. 56*bcb5dc79SHONG Yifan allow_files = True, 57*bcb5dc79SHONG Yifan mandatory = True, 58*bcb5dc79SHONG Yifan cfg = "target", 59*bcb5dc79SHONG Yifan doc = "path of the pre-built executable", 60*bcb5dc79SHONG Yifan ), 61*bcb5dc79SHONG Yifan "data": attr.label_list( 62*bcb5dc79SHONG Yifan allow_files = True, 63*bcb5dc79SHONG Yifan doc = "data dependencies. See" + 64*bcb5dc79SHONG Yifan " https://bazel.build/reference/be/common-definitions#typical.data", 65*bcb5dc79SHONG Yifan ), 66*bcb5dc79SHONG Yifan # "out" is attr.string instead of attr.output, so that it is select()'able. 67*bcb5dc79SHONG Yifan "out": attr.string( 68*bcb5dc79SHONG Yifan default = "", 69*bcb5dc79SHONG Yifan doc = "An output name for the copy of the binary. Defaults to " + 70*bcb5dc79SHONG Yifan "name.exe. (We add .exe to the name by default because it's " + 71*bcb5dc79SHONG Yifan "required on Windows and tolerated on other platforms.)", 72*bcb5dc79SHONG Yifan ), 73*bcb5dc79SHONG Yifan} 74*bcb5dc79SHONG Yifan 75*bcb5dc79SHONG Yifannative_binary = rule( 76*bcb5dc79SHONG Yifan implementation = _impl_rule, 77*bcb5dc79SHONG Yifan attrs = _ATTRS, 78*bcb5dc79SHONG Yifan executable = True, 79*bcb5dc79SHONG Yifan doc = """ 80*bcb5dc79SHONG YifanWraps a pre-built binary or script with a binary rule. 81*bcb5dc79SHONG Yifan 82*bcb5dc79SHONG YifanYou can "bazel run" this rule like any other binary rule, and use it as a tool 83*bcb5dc79SHONG Yifanin genrule.tools for example. You can also augment the binary with runfiles. 84*bcb5dc79SHONG Yifan""", 85*bcb5dc79SHONG Yifan) 86*bcb5dc79SHONG Yifan 87*bcb5dc79SHONG Yifannative_test = rule( 88*bcb5dc79SHONG Yifan implementation = _impl_rule, 89*bcb5dc79SHONG Yifan attrs = _ATTRS, 90*bcb5dc79SHONG Yifan test = True, 91*bcb5dc79SHONG Yifan doc = """ 92*bcb5dc79SHONG YifanWraps a pre-built binary or script with a test rule. 93*bcb5dc79SHONG Yifan 94*bcb5dc79SHONG YifanYou can "bazel test" this rule like any other test rule. You can also augment 95*bcb5dc79SHONG Yifanthe binary with runfiles. 96*bcb5dc79SHONG Yifan""", 97*bcb5dc79SHONG Yifan) 98