| # Copyright 2022 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. |
| |
| """A cc_library backed by a FIDL library.""" |
| |
| load(":providers.bzl", "FuchsiaFidlLibraryInfo") |
| |
| _CodegenInfo = provider("Carries generated information across FIDL bindings code generation ", fields = ["files"]) |
| |
| # ALL CODE BELOW IS DEPRECATED - TODO: REMOVE IT when soft transition is over |
| def _codegen_impl(context): |
| sdk = context.toolchains["@rules_fuchsia//fuchsia:toolchain"] |
| fidlgen = sdk.fidlgen_cpp if context.attr.binding_level == "llcpp" else sdk.fidlgen_hlcpp |
| |
| ir = context.attr.library[FuchsiaFidlLibraryInfo].ir |
| name = context.attr.library[FuchsiaFidlLibraryInfo].name |
| |
| base_path = context.attr.name + "." + context.attr.binding_level |
| |
| # This declaration is needed in order to get access to the full path. |
| root = context.actions.declare_directory(base_path) |
| headers = [] |
| sources = [] |
| if context.attr.binding_level == "llcpp": |
| dir = base_path + "/fidl/" + name + "/cpp" |
| header_files = [] |
| source_files = [] |
| |
| # common: |
| header_files.extend(["common_types.h", "markers.h"]) |
| source_files.extend(["common_types.cc"]) |
| |
| # wire types: |
| header_files.extend(["wire_types.h"]) |
| source_files.extend(["wire_types.cc"]) |
| |
| # wire zircon: |
| header_files.extend(["wire.h", "wire_messaging.h"]) |
| source_files.extend(["wire_messaging.cc"]) |
| |
| # wire channel testing: |
| header_files.extend(["wire_test_base.h"]) |
| |
| # natural types: |
| header_files.extend(["natural_types.h"]) |
| source_files.extend(["natural_types.cc"]) |
| |
| # wire/natural type conversions: |
| header_files.extend(["type_conversions.h"]) |
| source_files.extend(["type_conversions.cc"]) |
| |
| # unified zircon channel messaging: |
| header_files.extend(["fidl.h", "natural_messaging.h"]) |
| source_files.extend(["natural_messaging.cc"]) |
| |
| # TODO(fxbug.dev/108680): Better workaround for skipping codegen for zx. |
| if name == "zx": |
| source_files = ["markers.h"] |
| |
| for header in header_files: |
| headers.append(context.actions.declare_file(dir + "/" + header)) |
| for source in source_files: |
| sources.append(context.actions.declare_file(dir + "/" + source)) |
| |
| else: # context.attr.binding_level == "hlcpp" |
| dir = base_path + "/" + name.replace(".", "/") + "/cpp" |
| headers.append(context.actions.declare_file(dir + "/fidl.h")) |
| headers.append(context.actions.declare_file(dir + "/fidl_test_base.h")) |
| sources.append(context.actions.declare_file(dir + "/fidl.cc")) |
| |
| outputs = [root] + headers + sources |
| context.actions.run( |
| executable = fidlgen, |
| arguments = [ |
| "--json", |
| ir.path, |
| "--root", |
| root.path, |
| ], |
| inputs = [ |
| ir, |
| ], |
| outputs = outputs, |
| mnemonic = "FidlGenCc", |
| ) |
| |
| return [ |
| _CodegenInfo(files = depset(sources)), |
| DefaultInfo(files = depset(headers)), |
| ] |
| |
| def _impl_wrapper_impl(context): |
| files = context.attr.codegen[_CodegenInfo].files |
| return [DefaultInfo(files = files)] |
| |
| # 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, |
| toolchains = ["@rules_fuchsia//fuchsia:toolchain"], |
| # 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 = [FuchsiaFidlLibraryInfo], |
| ), |
| "binding_level": attr.string( |
| doc = "Controls whether to generate high- (hlcpp) or low-level (llcpp) C++ bindings.", |
| mandatory = True, |
| ), |
| }, |
| ) |
| |
| # 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 _fidl_cc_library(name, library, binding_level, deps = [], tags = [], **kwargs): |
| """Generates cc_library() for the given fidl_library. |
| |
| Args: |
| name: Target name. Required. |
| library: fidl_library() target to generate the language bindings for. Required. |
| binding_level: Controls whether to generate high- (hlcpp) or low-level (llcpp) C++ bindings. |
| deps: Additional dependencies. |
| tags: Optional tags. |
| **kwargs: Remaining args. |
| """ |
| gen_name = "%s_codegen" % name |
| impl_name = "%s_impl" % name |
| |
| _codegen( |
| name = gen_name, |
| library = library, |
| binding_level = binding_level, |
| ) |
| |
| _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, |
| ], |
| # This is necessary in order to locate generated headers. |
| strip_include_prefix = gen_name + "." + binding_level, |
| deps = deps, |
| tags = tags, |
| **kwargs |
| ) |
| |
| def fuchsia_fidl_hlcpp_library(name, library, deps = [], tags = [], **kwargs): |
| """Generates HLCPP cc_library() for the given fidl_library. |
| |
| DEPRECATED: use fuchsia_fidl_library instead. |
| |
| Args: |
| name: Target name. Required. |
| library: fidl_library() target to generate the language bindings for. Required. |
| deps: Additional dependencies. |
| tags: Optional tags. |
| **kwargs: Remaining args. |
| """ |
| _fidl_cc_library( |
| tags = tags, |
| name = name, |
| library = library, |
| binding_level = "hlcpp", |
| deps = deps, |
| **kwargs |
| ) |
| |
| def fuchsia_fidl_llcpp_library(name, library, deps = [], tags = [], **kwargs): |
| """Generates LLCPP cc_library() for the given fidl_library. |
| |
| DEPRECATED: use fuchsia_fidl_library instead. |
| |
| Args: |
| name: Target name. Required. |
| library: fidl_library() target to generate the language bindings for. Required. |
| deps: Additional dependencies. |
| tags: Optional tags. |
| **kwargs: Remaining args. |
| """ |
| _fidl_cc_library( |
| tags = tags, |
| name = name, |
| library = library, |
| binding_level = "llcpp", |
| deps = deps, |
| **kwargs |
| ) |