| # Copyright 2018 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| load(":fidl_library.bzl", "FidlLibraryInfo") |
| |
| # A cc_library backed by a FIDL library. |
| # |
| # Parameters |
| # |
| # library |
| # Label of the FIDL library. |
| |
| CodegenInfo = provider(fields=["impl"]) |
| |
| def _codegen_impl(context): |
| ir = context.attr.library[FidlLibraryInfo].ir |
| name = context.attr.library[FidlLibraryInfo].name |
| |
| base_path = context.attr.name + ".cc" |
| # This declaration is needed in order to get access to the full path. |
| output = context.actions.declare_directory(base_path) |
| stem = base_path + "/" + name.replace(".", "/") + "/cpp/fidl" |
| header = context.actions.declare_file(stem + ".h") |
| source = context.actions.declare_file(stem + ".cc") |
| |
| context.actions.run( |
| executable = context.executable._fidlgen, |
| arguments = [ |
| "--json", |
| ir.path, |
| "--output-base", |
| header.dirname + "/fidl", |
| "--include-base", |
| output.path, |
| "--generators", |
| "cpp", |
| ], |
| inputs = [ |
| ir, |
| ], |
| outputs = [ |
| header, |
| output, |
| source, |
| ], |
| mnemonic = "FidlGenCc", |
| ) |
| |
| return [ |
| CodegenInfo(impl = source), |
| DefaultInfo(files = depset([header])) |
| ] |
| |
| def _impl_wrapper_impl(context): |
| file = context.attr.codegen[CodegenInfo].impl |
| return [DefaultInfo(files = depset([file]))] |
| |
| # Runs fidlgen to produce both the header file and the implementation file. |
| # Only exposes the header as a source, as the two files need to be consumed by |
| # the cc_library as two separate rules. |
| _codegen = rule( |
| implementation = _codegen_impl, |
| # Files must be generated in genfiles in order for the header to be included |
| # anywhere. |
| output_to_genfiles = True, |
| attrs = { |
| "library": attr.label( |
| doc = "The FIDL library to generate code for", |
| mandatory = True, |
| allow_files = False, |
| providers = [FidlLibraryInfo], |
| ), |
| "_fidlgen": attr.label( |
| default = Label("//tools:fidlgen"), |
| allow_single_file = True, |
| executable = True, |
| cfg = "host", |
| ), |
| } |
| ) |
| |
| # Simply declares the implementation file generated by the codegen target as an |
| # output. |
| # This allows the implementation file to be exposed as a source in its own rule. |
| _impl_wrapper = rule( |
| implementation = _impl_wrapper_impl, |
| output_to_genfiles = True, |
| attrs = { |
| "codegen": attr.label( |
| doc = "The codegen rules generating the implementation file", |
| mandatory = True, |
| allow_files = False, |
| providers = [CodegenInfo], |
| ), |
| } |
| ) |
| |
| def cc_fidl_library(name, library, deps=[], tags=[], visibility=None): |
| gen_name = "%s_codegen" % name |
| impl_name = "%s_impl" % name |
| |
| _codegen( |
| name = gen_name, |
| library = library, |
| ) |
| |
| _impl_wrapper( |
| name = impl_name, |
| codegen = ":%s" % gen_name, |
| ) |
| |
| native.cc_library( |
| name = name, |
| hdrs = [ |
| ":%s" % gen_name, |
| ], |
| srcs = [ |
| ":%s" % impl_name, |
| # For the coding tables. |
| library, |
| ], |
| includes = [ |
| # This is necessary in order to locate generated headers. |
| gen_name + ".cc", |
| ], |
| deps = deps + [ |
| Label("//pkg/fidl_cpp"), |
| ], |
| tags = tags, |
| visibility = visibility, |
| ) |