Skip to content

Commit

Permalink
[Bazel/C++] Augment cc_dist_library to generate lists of source fil…
Browse files Browse the repository at this point in the history
…es (#10026)

This change largely moves internal logic that creates the the `CcFileList` provider from `build_systems.bzl` to `cc_dist_library.bzl`.

There are also some associated changes to the particular `cc_dist_library` targets, since the output didn't really make sense after previous BUILD.bazel refactoring. There is also a target now for `libprotoc`.
  • Loading branch information
dlj-NaN authored May 24, 2022
1 parent bbcc459 commit 586b72c
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 137 deletions.
28 changes: 22 additions & 6 deletions pkg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ gen_file_lists(
out_stem = "src_file_lists",
src_libs = {
# source rule: name in generated file
"//:protobuf": "libprotobuf",
"//src/google/protobuf/compiler:protoc_lib": "libprotoc",
"//:protobuf_lite": "libprotobuf_lite",
":protobuf": "libprotobuf",
":protoc": "libprotoc",
":protobuf_lite": "libprotobuf_lite",
},
)

Expand Down Expand Up @@ -343,8 +343,8 @@ cc_dist_library(
}),
tags = ["manual"],
deps = [
"//:protobuf_lite",
"//src/google/protobuf:arena",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/io",
"//src/google/protobuf/io:io_win32",
"//src/google/protobuf/stubs:lite",
Expand All @@ -362,15 +362,15 @@ cc_dist_library(
}),
tags = ["manual"],
deps = [
"//:protobuf",
"//:protobuf_lite",
"//src/google/protobuf:arena",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/io",
"//src/google/protobuf/io:gzip_stream",
"//src/google/protobuf/io:io_win32",
"//src/google/protobuf/io:printer",
"//src/google/protobuf/io:tokenizer",
"//src/google/protobuf:protobuf",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/stubs",
"//src/google/protobuf/stubs:lite",
"//src/google/protobuf/util:delimited_message_util",
Expand All @@ -382,6 +382,22 @@ cc_dist_library(
],
)

cc_dist_library(
name = "protoc",
tags = ["manual"],
deps = [
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf/compiler:command_line_interface",
"//src/google/protobuf/compiler/cpp",
"//src/google/protobuf/compiler/csharp",
"//src/google/protobuf/compiler/java",
"//src/google/protobuf/compiler/objectivec",
"//src/google/protobuf/compiler/php",
"//src/google/protobuf/compiler/python",
"//src/google/protobuf/compiler/ruby",
],
)

################################################################################
# Distribution sources
################################################################################
Expand Down
78 changes: 14 additions & 64 deletions pkg/build_systems.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Starlark utilities for working with other build systems

load("@rules_pkg//:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
load(":cc_dist_library.bzl", "CcFileList")

################################################################################
# Macro to create CMake and Automake source lists.
Expand Down Expand Up @@ -31,21 +32,6 @@ def gen_file_lists(name, out_stem, **kwargs):
# Aspect that extracts srcs, hdrs, etc.
################################################################################

CcFileList = provider(
doc = "List of files to be built into a library.",
fields = {
# As a rule of thumb, `hdrs` and `textual_hdrs` are the files that
# would be installed along with a prebuilt library.
"hdrs": "public header files, including those used by generated code",
"textual_hdrs": "files which are included but are not self-contained",

# The `internal_hdrs` are header files which appear in `srcs`.
# These are only used when compiling the library.
"internal_hdrs": "internal header files (only used to build .cc files)",
"srcs": "source files",
},
)

ProtoFileList = provider(
doc = "List of proto files and generated code to be built into a library.",
fields = {
Expand All @@ -65,56 +51,11 @@ def _flatten_target_files(targets):
files.append(tfile)
return files

def _combine_cc_file_lists(file_lists):
hdrs = {}
textual_hdrs = {}
internal_hdrs = {}
srcs = {}
for file_list in file_lists:
hdrs.update({f: 1 for f in file_list.hdrs})
textual_hdrs.update({f: 1 for f in file_list.textual_hdrs})
internal_hdrs.update({f: 1 for f in file_list.internal_hdrs})
srcs.update({f: 1 for f in file_list.srcs})
return CcFileList(
hdrs = sorted(hdrs.keys()),
textual_hdrs = sorted(textual_hdrs.keys()),
internal_hdrs = sorted(internal_hdrs.keys()),
srcs = sorted(srcs.keys()),
)

def _file_list_aspect_impl(target, ctx):
# We're going to reach directly into the attrs on the traversed rule.
rule_attr = ctx.rule.attr
providers = []

# Extract sources from a `cc_library` (or similar):
if CcInfo in target:
# CcInfo is a proxy for what we expect this rule to look like.
# However, some deps may expose `CcInfo` without having `srcs`,
# `hdrs`, etc., so we use `getattr` to handle that gracefully.

internal_hdrs = []
srcs = []

# Filter `srcs` so it only contains source files. Headers will go
# into `internal_headers`.
for src in _flatten_target_files(getattr(rule_attr, "srcs", [])):
if src.extension.lower() in ["c", "cc", "cpp", "cxx"]:
srcs.append(src)
else:
internal_hdrs.append(src)

providers.append(CcFileList(
hdrs = _flatten_target_files(getattr(rule_attr, "hdrs", [])),
textual_hdrs = _flatten_target_files(getattr(
rule_attr,
"textual_hdrs",
[],
)),
internal_hdrs = internal_hdrs,
srcs = srcs,
))

# Extract sources from a `proto_library`:
if ProtoInfo in target:
proto_srcs = []
Expand Down Expand Up @@ -197,19 +138,28 @@ def _create_file_list_impl(ctx, fragment_generator):
for srcrule, libname in ctx.attr.src_libs.items():
if CcFileList in srcrule:
cc_file_list = srcrule[CcFileList]

# Turn depsets of files into sorted lists.
srcs = sorted(cc_file_list.srcs.to_list())
hdrs = sorted(
depset(transitive = [
cc_file_list.textual_hdrs,
cc_file_list.hdrs,
]).to_list(),
)

fragments.extend([
fragment_generator(
srcrule.label,
libname + "_srcs",
ctx.attr.source_prefix,
[f.short_path for f in cc_file_list.srcs],
[f.short_path for f in srcs],
),
fragment_generator(
srcrule.label,
libname + "_hdrs",
ctx.attr.source_prefix,
[f.short_path for f in (cc_file_list.hdrs +
cc_file_list.textual_hdrs)],
[f.short_path for f in hdrs],
),
])

Expand Down Expand Up @@ -247,7 +197,7 @@ def _create_file_list_impl(ctx, fragment_generator):
# keys are the destination:
files.update(srcrule[PackageFilesInfo].dest_src_map)

if files == {} and DefaultInfo in srcrule and CcInfo not in srcrule:
if files == {} and DefaultInfo in srcrule and CcFileList not in srcrule:
# This could be an individual file or filegroup.
# We explicitly ignore rules with CcInfo, since their
# output artifacts are libraries or binaries.
Expand Down
Loading

0 comments on commit 586b72c

Please sign in to comment.