xref: /aosp_15_r20/build/bazel/rules/cc/cc_yacc_library.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
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