1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Worker 17*7594170eSAndroid Build Coastguard Worker# A rule to generate files based on provided srcs and tools 18*7594170eSAndroid Build Coastguard Workerdef _gensrcs_impl(ctx): 19*7594170eSAndroid Build Coastguard Worker # The next two assignments can be created by using ctx.resolve_command 20*7594170eSAndroid Build Coastguard Worker # TODO: Switch to using ctx.resolve_command when it is out of experimental 21*7594170eSAndroid Build Coastguard Worker command = ctx.expand_location(ctx.attr.cmd, targets = ctx.attr.data) 22*7594170eSAndroid Build Coastguard Worker tools = [ 23*7594170eSAndroid Build Coastguard Worker tool[DefaultInfo].files_to_run 24*7594170eSAndroid Build Coastguard Worker for tool in ctx.attr.tools 25*7594170eSAndroid Build Coastguard Worker ] 26*7594170eSAndroid Build Coastguard Worker 27*7594170eSAndroid Build Coastguard Worker command = command.replace( 28*7594170eSAndroid Build Coastguard Worker "$(RULEDIR)", 29*7594170eSAndroid Build Coastguard Worker paths.join( 30*7594170eSAndroid Build Coastguard Worker ctx.var["GENDIR"], 31*7594170eSAndroid Build Coastguard Worker ctx.label.package, 32*7594170eSAndroid Build Coastguard Worker ), 33*7594170eSAndroid Build Coastguard Worker ) 34*7594170eSAndroid Build Coastguard Worker 35*7594170eSAndroid Build Coastguard Worker in_files = ctx.files.srcs 36*7594170eSAndroid Build Coastguard Worker out_files = [] 37*7594170eSAndroid Build Coastguard Worker for in_file in in_files: 38*7594170eSAndroid Build Coastguard Worker # <path-to-in_file>/out_file 39*7594170eSAndroid Build Coastguard Worker # where path-to-in_file is relative to the workspace 40*7594170eSAndroid Build Coastguard Worker out_file_path = paths.join( 41*7594170eSAndroid Build Coastguard Worker paths.dirname(in_file.short_path), 42*7594170eSAndroid Build Coastguard Worker paths.replace_extension( 43*7594170eSAndroid Build Coastguard Worker in_file.basename, 44*7594170eSAndroid Build Coastguard Worker "." + ctx.attr.output_extension, 45*7594170eSAndroid Build Coastguard Worker ), 46*7594170eSAndroid Build Coastguard Worker ) 47*7594170eSAndroid Build Coastguard Worker 48*7594170eSAndroid Build Coastguard Worker # out_file is at output_file_path that is relative to <GENDIR>/<package-dir> 49*7594170eSAndroid Build Coastguard Worker # Hence, the fullpath to out_file is 50*7594170eSAndroid Build Coastguard Worker # <GENDIR>/<package-dir>/<path-to-in_file>/out_file 51*7594170eSAndroid Build Coastguard Worker out_file = ctx.actions.declare_file(out_file_path) 52*7594170eSAndroid Build Coastguard Worker shell_command = command \ 53*7594170eSAndroid Build Coastguard Worker .replace("$(SRC)", in_file.path) \ 54*7594170eSAndroid Build Coastguard Worker .replace("$(OUT)", out_file.path) 55*7594170eSAndroid Build Coastguard Worker ctx.actions.run_shell( 56*7594170eSAndroid Build Coastguard Worker tools = tools, 57*7594170eSAndroid Build Coastguard Worker outputs = [out_file], 58*7594170eSAndroid Build Coastguard Worker inputs = in_files + ctx.files.data, 59*7594170eSAndroid Build Coastguard Worker command = shell_command, 60*7594170eSAndroid Build Coastguard Worker progress_message = "Generating %s from %s" % ( 61*7594170eSAndroid Build Coastguard Worker out_file.path, 62*7594170eSAndroid Build Coastguard Worker in_file.path, 63*7594170eSAndroid Build Coastguard Worker ), 64*7594170eSAndroid Build Coastguard Worker ) 65*7594170eSAndroid Build Coastguard Worker out_files.append(out_file) 66*7594170eSAndroid Build Coastguard Worker 67*7594170eSAndroid Build Coastguard Worker return [DefaultInfo( 68*7594170eSAndroid Build Coastguard Worker files = depset(out_files), 69*7594170eSAndroid Build Coastguard Worker )] 70*7594170eSAndroid Build Coastguard Worker 71*7594170eSAndroid Build Coastguard Workergensrcs = rule( 72*7594170eSAndroid Build Coastguard Worker implementation = _gensrcs_impl, 73*7594170eSAndroid Build Coastguard Worker doc = "This rule generates files, where each of the `srcs` files is " + 74*7594170eSAndroid Build Coastguard Worker "passed into the custom shell command`", 75*7594170eSAndroid Build Coastguard Worker attrs = { 76*7594170eSAndroid Build Coastguard Worker "srcs": attr.label_list( 77*7594170eSAndroid Build Coastguard Worker allow_files = True, 78*7594170eSAndroid Build Coastguard Worker mandatory = True, 79*7594170eSAndroid Build Coastguard Worker doc = "A list of inputs such as source files to process", 80*7594170eSAndroid Build Coastguard Worker ), 81*7594170eSAndroid Build Coastguard Worker "output_extension": attr.string( 82*7594170eSAndroid Build Coastguard Worker doc = "The extension that will be substituted for output files", 83*7594170eSAndroid Build Coastguard Worker ), 84*7594170eSAndroid Build Coastguard Worker "cmd": attr.string( 85*7594170eSAndroid Build Coastguard Worker mandatory = True, 86*7594170eSAndroid Build Coastguard Worker doc = "The command to run. Subject to $(location) expansion. " + 87*7594170eSAndroid Build Coastguard Worker "$(IN) represents each input file provided in `srcs` " + 88*7594170eSAndroid Build Coastguard Worker "while $(OUT) reprensents corresponding output file " + 89*7594170eSAndroid Build Coastguard Worker "generated by the rule. $(RULEDIR) is intepreted the same " + 90*7594170eSAndroid Build Coastguard Worker "as it is in genrule.", 91*7594170eSAndroid Build Coastguard Worker ), 92*7594170eSAndroid Build Coastguard Worker "tools": attr.label_list( 93*7594170eSAndroid Build Coastguard Worker allow_files = True, 94*7594170eSAndroid Build Coastguard Worker doc = "A list of tool dependencies for this rule. " + 95*7594170eSAndroid Build Coastguard Worker "The path of an individual `tools` target //x:y can be " + 96*7594170eSAndroid Build Coastguard Worker "obtained using `$(location //x:y)`", 97*7594170eSAndroid Build Coastguard Worker cfg = "exec", 98*7594170eSAndroid Build Coastguard Worker ), 99*7594170eSAndroid Build Coastguard Worker "data": attr.label_list( 100*7594170eSAndroid Build Coastguard Worker allow_files = True, 101*7594170eSAndroid Build Coastguard Worker doc = "Additional files needed for build that are not tooling " + 102*7594170eSAndroid Build Coastguard Worker "related.", 103*7594170eSAndroid Build Coastguard Worker ), 104*7594170eSAndroid Build Coastguard Worker }, 105*7594170eSAndroid Build Coastguard Worker) 106