1*7594170eSAndroid Build Coastguard Worker"""Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker 3*7594170eSAndroid Build Coastguard WorkerLicensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Workeryou may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard WorkerYou 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 WorkerUnless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Workerlimitations under the License. 14*7594170eSAndroid Build Coastguard Worker""" 15*7594170eSAndroid Build Coastguard Worker 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 17*7594170eSAndroid Build Coastguard Worker 18*7594170eSAndroid Build Coastguard Worker"""Build rule for converting `.l` or `.ll` to C or C++ sources with Flex. 19*7594170eSAndroid Build Coastguard Worker 20*7594170eSAndroid Build Coastguard WorkerUses flex (and m4 under the hood) to convert .l and .ll source files into 21*7594170eSAndroid Build Coastguard Worker.c and .cc files. Does not support .lex or .lpp extensions 22*7594170eSAndroid Build Coastguard Worker 23*7594170eSAndroid Build Coastguard WorkerExamples 24*7594170eSAndroid Build Coastguard Worker-------- 25*7594170eSAndroid Build Coastguard Worker 26*7594170eSAndroid Build Coastguard WorkerThis is a simple example. 27*7594170eSAndroid Build Coastguard Worker``` 28*7594170eSAndroid Build Coastguard Workergenlex( 29*7594170eSAndroid Build Coastguard Worker name = "html_lex", 30*7594170eSAndroid Build Coastguard Worker src = "html.l", 31*7594170eSAndroid Build Coastguard Worker) 32*7594170eSAndroid Build Coastguard Worker``` 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard WorkerThis example uses some options for flex. 35*7594170eSAndroid Build Coastguard Worker``` 36*7594170eSAndroid Build Coastguard Workergenlex( 37*7594170eSAndroid Build Coastguard Worker name = "rules_l", 38*7594170eSAndroid Build Coastguard Worker src = "rules.l", 39*7594170eSAndroid Build Coastguard Worker lexopts = ["-d", "-v"], 40*7594170eSAndroid Build Coastguard Worker) 41*7594170eSAndroid Build Coastguard Worker``` 42*7594170eSAndroid Build Coastguard Worker""" 43*7594170eSAndroid Build Coastguard Worker 44*7594170eSAndroid Build Coastguard Workerdef _genlex_impl(ctx): 45*7594170eSAndroid Build Coastguard Worker """Implementation for genlex rule.""" 46*7594170eSAndroid Build Coastguard Worker 47*7594170eSAndroid Build Coastguard Worker # TODO(b/190006308): When fixed, l and ll sources can coexist. Remove this. 48*7594170eSAndroid Build Coastguard Worker exts = [f.extension for f in ctx.files.srcs] 49*7594170eSAndroid Build Coastguard Worker contains_l = False 50*7594170eSAndroid Build Coastguard Worker contains_ll = False 51*7594170eSAndroid Build Coastguard Worker for ext in exts: 52*7594170eSAndroid Build Coastguard Worker if ext == "l": 53*7594170eSAndroid Build Coastguard Worker contains_l = True 54*7594170eSAndroid Build Coastguard Worker if ext == "ll": 55*7594170eSAndroid Build Coastguard Worker contains_ll = True 56*7594170eSAndroid Build Coastguard Worker if contains_l and contains_ll: 57*7594170eSAndroid Build Coastguard Worker fail( 58*7594170eSAndroid Build Coastguard Worker "srcs contains both .l and .ll files. Please use separate targets.", 59*7594170eSAndroid Build Coastguard Worker ) 60*7594170eSAndroid Build Coastguard Worker 61*7594170eSAndroid Build Coastguard Worker outputs = [] 62*7594170eSAndroid Build Coastguard Worker for src_file in ctx.files.srcs: 63*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 64*7594170eSAndroid Build Coastguard Worker output_filename = "" 65*7594170eSAndroid Build Coastguard Worker 66*7594170eSAndroid Build Coastguard Worker src_ext = src_file.extension 67*7594170eSAndroid Build Coastguard Worker split_filename = src_file.basename.partition(".") 68*7594170eSAndroid Build Coastguard Worker filename_without_ext = split_filename[0] 69*7594170eSAndroid Build Coastguard Worker 70*7594170eSAndroid Build Coastguard Worker if src_ext == "l": 71*7594170eSAndroid Build Coastguard Worker output_filename = paths.replace_extension(filename_without_ext, ".c") 72*7594170eSAndroid Build Coastguard Worker elif src_ext == "ll": 73*7594170eSAndroid Build Coastguard Worker output_filename = paths.replace_extension(filename_without_ext, ".cc") 74*7594170eSAndroid Build Coastguard Worker output_file = ctx.actions.declare_file(output_filename) 75*7594170eSAndroid Build Coastguard Worker outputs.append(output_file) 76*7594170eSAndroid Build Coastguard Worker args.add("-o", output_file.path) 77*7594170eSAndroid Build Coastguard Worker 78*7594170eSAndroid Build Coastguard Worker args.add_all(ctx.attr.lexopts) 79*7594170eSAndroid Build Coastguard Worker args.add(src_file) 80*7594170eSAndroid Build Coastguard Worker 81*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 82*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._flex, 83*7594170eSAndroid Build Coastguard Worker env = { 84*7594170eSAndroid Build Coastguard Worker "M4": ctx.executable._m4.path, 85*7594170eSAndroid Build Coastguard Worker }, 86*7594170eSAndroid Build Coastguard Worker arguments = [args], 87*7594170eSAndroid Build Coastguard Worker inputs = [src_file], 88*7594170eSAndroid Build Coastguard Worker tools = [ctx.executable._m4], 89*7594170eSAndroid Build Coastguard Worker outputs = [output_file], 90*7594170eSAndroid Build Coastguard Worker mnemonic = "Flex", 91*7594170eSAndroid Build Coastguard Worker progress_message = "Generating %s from %s" % ( 92*7594170eSAndroid Build Coastguard Worker output_filename, 93*7594170eSAndroid Build Coastguard Worker src_file.short_path, 94*7594170eSAndroid Build Coastguard Worker ), 95*7594170eSAndroid Build Coastguard Worker ) 96*7594170eSAndroid Build Coastguard Worker return [DefaultInfo(files = depset(outputs))] 97*7594170eSAndroid Build Coastguard Worker 98*7594170eSAndroid Build Coastguard Workergenlex = rule( 99*7594170eSAndroid Build Coastguard Worker implementation = _genlex_impl, 100*7594170eSAndroid Build Coastguard Worker doc = "Generate C/C++-language sources from a lex file using Flex.", 101*7594170eSAndroid Build Coastguard Worker attrs = { 102*7594170eSAndroid Build Coastguard Worker "srcs": attr.label_list( 103*7594170eSAndroid Build Coastguard Worker mandatory = True, 104*7594170eSAndroid Build Coastguard Worker allow_files = [".l", ".ll"], 105*7594170eSAndroid Build Coastguard Worker doc = "The lex source file for this rule", 106*7594170eSAndroid Build Coastguard Worker ), 107*7594170eSAndroid Build Coastguard Worker "lexopts": attr.string_list( 108*7594170eSAndroid Build Coastguard Worker doc = "A list of options to be added to the flex command line.", 109*7594170eSAndroid Build Coastguard Worker ), 110*7594170eSAndroid Build Coastguard Worker "_flex": attr.label( 111*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/build-tools:flex", 112*7594170eSAndroid Build Coastguard Worker executable = True, 113*7594170eSAndroid Build Coastguard Worker cfg = "exec", 114*7594170eSAndroid Build Coastguard Worker ), 115*7594170eSAndroid Build Coastguard Worker "_m4": attr.label( 116*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/build-tools:m4", 117*7594170eSAndroid Build Coastguard Worker executable = True, 118*7594170eSAndroid Build Coastguard Worker cfg = "exec", 119*7594170eSAndroid Build Coastguard Worker ), 120*7594170eSAndroid Build Coastguard Worker }, 121*7594170eSAndroid Build Coastguard Worker) 122