1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2023 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 Workerload(":cc_library_common.bzl", "create_ccinfo_for_includes") 17*7594170eSAndroid Build Coastguard Workerload(":cc_library_static.bzl", "cc_library_static") 18*7594170eSAndroid Build Coastguard Worker 19*7594170eSAndroid Build Coastguard Worker""" 20*7594170eSAndroid Build Coastguard WorkerGenerate C/C++ parser from a .y/.yy grammar file. 21*7594170eSAndroid Build Coastguard WorkerThe generated file might depend on external headers and has to be compiled 22*7594170eSAndroid Build Coastguard Workerseparately. 23*7594170eSAndroid Build Coastguard Worker""" 24*7594170eSAndroid Build Coastguard Worker 25*7594170eSAndroid Build Coastguard Workerdef _cc_yacc_parser_gen_impl(ctx): 26*7594170eSAndroid Build Coastguard Worker ext = ".c" 27*7594170eSAndroid Build Coastguard Worker if paths.split_extension(ctx.file.src.basename)[1] == ".yy": 28*7594170eSAndroid Build Coastguard Worker ext = ".cpp" 29*7594170eSAndroid Build Coastguard Worker 30*7594170eSAndroid Build Coastguard Worker # C/CPP file 31*7594170eSAndroid Build Coastguard Worker output_c_file = ctx.actions.declare_file( 32*7594170eSAndroid Build Coastguard Worker paths.join( 33*7594170eSAndroid Build Coastguard Worker ctx.attr.name, # Prevent name collisions (esp for tests) 34*7594170eSAndroid Build Coastguard Worker paths.replace_extension(ctx.file.src.basename, ext), 35*7594170eSAndroid Build Coastguard Worker ), 36*7594170eSAndroid Build Coastguard Worker ) 37*7594170eSAndroid Build Coastguard Worker 38*7594170eSAndroid Build Coastguard Worker # Header file 39*7594170eSAndroid Build Coastguard Worker output_h_file = ctx.actions.declare_file( 40*7594170eSAndroid Build Coastguard Worker paths.join( 41*7594170eSAndroid Build Coastguard Worker ctx.attr.name, # Prevent name collisions (esp for tests) 42*7594170eSAndroid Build Coastguard Worker paths.replace_extension(ctx.file.src.basename, ".h"), 43*7594170eSAndroid Build Coastguard Worker ), 44*7594170eSAndroid Build Coastguard Worker ) 45*7594170eSAndroid Build Coastguard Worker outputs = [ 46*7594170eSAndroid Build Coastguard Worker output_c_file, 47*7594170eSAndroid Build Coastguard Worker output_h_file, 48*7594170eSAndroid Build Coastguard Worker ] 49*7594170eSAndroid Build Coastguard Worker output_hdrs = [ 50*7594170eSAndroid Build Coastguard Worker output_h_file, 51*7594170eSAndroid Build Coastguard Worker ] 52*7594170eSAndroid Build Coastguard Worker 53*7594170eSAndroid Build Coastguard Worker # Path of location.hh in the same dir as the generated C/CPP file 54*7594170eSAndroid Build Coastguard Worker if ctx.attr.gen_location_hh: 55*7594170eSAndroid Build Coastguard Worker location_hh_file = ctx.actions.declare_file( 56*7594170eSAndroid Build Coastguard Worker paths.join( 57*7594170eSAndroid Build Coastguard Worker ctx.attr.name, 58*7594170eSAndroid Build Coastguard Worker "location.hh", 59*7594170eSAndroid Build Coastguard Worker ), 60*7594170eSAndroid Build Coastguard Worker ) 61*7594170eSAndroid Build Coastguard Worker outputs.append(location_hh_file) 62*7594170eSAndroid Build Coastguard Worker output_hdrs.append(location_hh_file) 63*7594170eSAndroid Build Coastguard Worker 64*7594170eSAndroid Build Coastguard Worker # Path of position.hh in the same dir as the generated C/CPP file 65*7594170eSAndroid Build Coastguard Worker if ctx.attr.gen_position_hh: 66*7594170eSAndroid Build Coastguard Worker position_hh_file = ctx.actions.declare_file( 67*7594170eSAndroid Build Coastguard Worker paths.join( 68*7594170eSAndroid Build Coastguard Worker ctx.attr.name, 69*7594170eSAndroid Build Coastguard Worker "position.hh", 70*7594170eSAndroid Build Coastguard Worker ), 71*7594170eSAndroid Build Coastguard Worker ) 72*7594170eSAndroid Build Coastguard Worker outputs.append(position_hh_file) 73*7594170eSAndroid Build Coastguard Worker output_hdrs.append(position_hh_file) 74*7594170eSAndroid Build Coastguard Worker 75*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 76*7594170eSAndroid Build Coastguard Worker args.add("-d") # Generate headers 77*7594170eSAndroid Build Coastguard Worker args.add_all(ctx.attr.flags) 78*7594170eSAndroid Build Coastguard Worker args.add("--defines=" + output_h_file.path) 79*7594170eSAndroid Build Coastguard Worker args.add("-o", output_c_file) 80*7594170eSAndroid Build Coastguard Worker args.add(ctx.file.src) 81*7594170eSAndroid Build Coastguard Worker 82*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 83*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._bison, 84*7594170eSAndroid Build Coastguard Worker inputs = [ctx.file.src], 85*7594170eSAndroid Build Coastguard Worker outputs = outputs, 86*7594170eSAndroid Build Coastguard Worker arguments = [args], 87*7594170eSAndroid Build Coastguard Worker # Explicitly set some environment variables to ensure Android's hermetic tools are used. 88*7594170eSAndroid Build Coastguard Worker env = { 89*7594170eSAndroid Build Coastguard Worker "BISON_PKGDATADIR": "prebuilts/build-tools/common/bison", 90*7594170eSAndroid Build Coastguard Worker "M4": ctx.executable._m4.path, 91*7594170eSAndroid Build Coastguard Worker }, 92*7594170eSAndroid Build Coastguard Worker tools = [ctx.executable._m4] + ctx.files._bison_runfiles, 93*7594170eSAndroid Build Coastguard Worker mnemonic = "YaccCompile", 94*7594170eSAndroid Build Coastguard Worker ) 95*7594170eSAndroid Build Coastguard Worker 96*7594170eSAndroid Build Coastguard Worker return [ 97*7594170eSAndroid Build Coastguard Worker DefaultInfo( 98*7594170eSAndroid Build Coastguard Worker # Return the C/C++ file. 99*7594170eSAndroid Build Coastguard Worker # Skip headers since rdep does not compile headers. 100*7594170eSAndroid Build Coastguard Worker files = depset([output_c_file]), 101*7594170eSAndroid Build Coastguard Worker ), 102*7594170eSAndroid Build Coastguard Worker create_ccinfo_for_includes( 103*7594170eSAndroid Build Coastguard Worker ctx, 104*7594170eSAndroid Build Coastguard Worker hdrs = output_hdrs, 105*7594170eSAndroid Build Coastguard Worker includes = [ctx.attr.name], 106*7594170eSAndroid Build Coastguard Worker ), 107*7594170eSAndroid Build Coastguard Worker ] 108*7594170eSAndroid Build Coastguard Worker 109*7594170eSAndroid Build Coastguard Worker_cc_yacc_parser_gen = rule( 110*7594170eSAndroid Build Coastguard Worker implementation = _cc_yacc_parser_gen_impl, 111*7594170eSAndroid Build Coastguard Worker doc = "This rule generates a C/C++ parser from a .y/.yy grammar file using bison", 112*7594170eSAndroid Build Coastguard Worker attrs = { 113*7594170eSAndroid Build Coastguard Worker "src": attr.label( 114*7594170eSAndroid Build Coastguard Worker allow_single_file = [".y", ".yy"], 115*7594170eSAndroid Build Coastguard Worker doc = "The grammar file for the parser", 116*7594170eSAndroid Build Coastguard Worker ), 117*7594170eSAndroid Build Coastguard Worker "flags": attr.string_list( 118*7594170eSAndroid Build Coastguard Worker default = [], 119*7594170eSAndroid Build Coastguard Worker doc = "List of flags that will be used in yacc compile", 120*7594170eSAndroid Build Coastguard Worker ), 121*7594170eSAndroid Build Coastguard Worker "gen_location_hh": attr.bool( 122*7594170eSAndroid Build Coastguard Worker default = False, 123*7594170eSAndroid Build Coastguard Worker doc = "Whether the yacc file will produce a location.hh file.", 124*7594170eSAndroid Build Coastguard Worker ), 125*7594170eSAndroid Build Coastguard Worker "gen_position_hh": attr.bool( 126*7594170eSAndroid Build Coastguard Worker default = False, 127*7594170eSAndroid Build Coastguard Worker doc = "Whether the yacc file will produce a location.hh file.", 128*7594170eSAndroid Build Coastguard Worker ), 129*7594170eSAndroid Build Coastguard Worker "_m4": attr.label( 130*7594170eSAndroid Build Coastguard Worker executable = True, 131*7594170eSAndroid Build Coastguard Worker cfg = "exec", 132*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/build-tools:m4"), 133*7594170eSAndroid Build Coastguard Worker ), 134*7594170eSAndroid Build Coastguard Worker "_bison": attr.label( 135*7594170eSAndroid Build Coastguard Worker executable = True, 136*7594170eSAndroid Build Coastguard Worker cfg = "exec", 137*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/build-tools:bison"), 138*7594170eSAndroid Build Coastguard Worker ), 139*7594170eSAndroid Build Coastguard Worker "_bison_runfiles": attr.label( 140*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/build-tools:bison.runfiles"), 141*7594170eSAndroid Build Coastguard Worker ), 142*7594170eSAndroid Build Coastguard Worker }, 143*7594170eSAndroid Build Coastguard Worker provides = [ 144*7594170eSAndroid Build Coastguard Worker CcInfo, 145*7594170eSAndroid Build Coastguard Worker ], 146*7594170eSAndroid Build Coastguard Worker) 147*7594170eSAndroid Build Coastguard Worker 148*7594170eSAndroid Build Coastguard Workerdef cc_yacc_static_library( 149*7594170eSAndroid Build Coastguard Worker name, 150*7594170eSAndroid Build Coastguard Worker src, 151*7594170eSAndroid Build Coastguard Worker flags = [], 152*7594170eSAndroid Build Coastguard Worker gen_location_hh = False, 153*7594170eSAndroid Build Coastguard Worker gen_position_hh = False, 154*7594170eSAndroid Build Coastguard Worker local_includes = [], 155*7594170eSAndroid Build Coastguard Worker implementation_deps = [], 156*7594170eSAndroid Build Coastguard Worker implementation_dynamic_deps = [], 157*7594170eSAndroid Build Coastguard Worker **kwargs): 158*7594170eSAndroid Build Coastguard Worker """ 159*7594170eSAndroid Build Coastguard Worker Generate C/C++ parser from .y/.yy grammar file and wrap it in a cc_library_static target. 160*7594170eSAndroid Build Coastguard Worker 161*7594170eSAndroid Build Coastguard Worker """ 162*7594170eSAndroid Build Coastguard Worker _output_parser = name + "_parser" 163*7594170eSAndroid Build Coastguard Worker 164*7594170eSAndroid Build Coastguard Worker _cc_yacc_parser_gen( 165*7594170eSAndroid Build Coastguard Worker name = _output_parser, 166*7594170eSAndroid Build Coastguard Worker src = src, 167*7594170eSAndroid Build Coastguard Worker flags = flags, 168*7594170eSAndroid Build Coastguard Worker gen_location_hh = gen_location_hh, 169*7594170eSAndroid Build Coastguard Worker gen_position_hh = gen_position_hh, 170*7594170eSAndroid Build Coastguard Worker **kwargs 171*7594170eSAndroid Build Coastguard Worker ) 172*7594170eSAndroid Build Coastguard Worker 173*7594170eSAndroid Build Coastguard Worker cc_library_static( 174*7594170eSAndroid Build Coastguard Worker name = name, 175*7594170eSAndroid Build Coastguard Worker srcs = [_output_parser], 176*7594170eSAndroid Build Coastguard Worker deps = [_output_parser], # Generated hdrs 177*7594170eSAndroid Build Coastguard Worker local_includes = local_includes, 178*7594170eSAndroid Build Coastguard Worker implementation_deps = implementation_deps, 179*7594170eSAndroid Build Coastguard Worker implementation_dynamic_deps = implementation_dynamic_deps, 180*7594170eSAndroid Build Coastguard Worker **kwargs 181*7594170eSAndroid Build Coastguard Worker ) 182