@ -134,12 +134,16 @@ CcFileList = provider(
)
def _flatten_target_files ( targets ) :
return depset ( transitive = [ target . files for target in targets ] )
return depset ( transitive = [
target . files
for target in targets
# Filter out targets from external workspaces
if target . label . workspace_name == " " or
target . label . workspace_name == " com_google_protobuf "
] )
files = [ ]
for target in targets :
files . extend ( target . files . to_list ( ) )
return files
def _get_transitive_sources ( targets , attr , deps ) :
return depset ( targets , transitive = [ getattr ( dep [ CcFileList ] , attr ) for dep in deps if CcFileList in dep ] )
def _cc_file_list_aspect_impl ( target , ctx ) :
# Extract sources from a `cc_library` (or similar):
@ -165,14 +169,22 @@ def _cc_file_list_aspect_impl(target, ctx):
internal_hdrs . append ( src )
return [ CcFileList (
hdrs = _flatten_target_files ( getattr ( rule_attr , " hdrs " , depset ( ) ) ) ,
textual_hdrs = _flatten_target_files ( getattr (
rule_attr ,
hdrs = _get_transitive_sources (
_flatten_target_files ( rule_attr . hdrs ) . to_list ( ) ,
" hdrs " ,
rule_attr . deps ,
) ,
textual_hdrs = _get_transitive_sources (
_flatten_target_files ( rule_attr . textual_hdrs ) . to_list ( ) ,
" textual_hdrs " ,
depset ( ) ,
) ) ,
internal_hdrs = depset ( internal_hdrs ) ,
srcs = depset ( srcs ) ,
rule_attr . deps ,
) ,
internal_hdrs = _get_transitive_sources (
internal_hdrs ,
" internal_hdrs " ,
rule_attr . deps ,
) ,
srcs = _get_transitive_sources ( srcs , " srcs " , rule_attr . deps ) ,
) ]
cc_file_list_aspect = aspect (
@ -198,7 +210,9 @@ Output is CcFileList. Example:
# srcs = depset([File("foo.cc")]),
# )
""" ,
required_providers = [ CcInfo ] ,
implementation = _cc_file_list_aspect_impl ,
attr_aspects = [ " deps " ] ,
)
################################################################################
@ -206,10 +220,10 @@ Output is CcFileList. Example:
################################################################################
def _collect_inputs ( deps ) :
""" Collects files from a list of immediate deps.
""" Collects files from a list of deps.
This rule collects source files and linker inputs for C + + deps . Only
these immediate deps are considered , not transitive deps .
This rule collects source files and linker inputs transitively for C + +
deps .
The return value is a struct with object files ( linker inputs ) ,
partitioned by PIC and non - pic , and the rules ' source and header files:
@ -221,9 +235,8 @@ def _collect_inputs(deps):
)
Args :
deps : Iterable of immediate deps . These will be treated as the " inputs, "
but not the transitive deps .
deps : Iterable of immediate deps , which will be treated as roots to
recurse transitively .
Returns :
A struct with linker inputs , source files , and header files .
"""
@ -265,6 +278,27 @@ def _collect_inputs(deps):
) ,
)
# Given structs a and b returned from _collect_inputs(), returns a copy of a
# but with all files from b subtracted out.
def _subtract_files ( a , b ) :
result_args = { }
top_level_fields = [ " objects " , " pic_objects " ]
for field in top_level_fields :
to_remove = { e : None for e in getattr ( b , field ) }
result_args [ field ] = [ e for e in getattr ( a , field ) if not e in to_remove ]
cc_file_list_args = { }
file_list_fields = [ " srcs " , " hdrs " , " internal_hdrs " , " textual_hdrs " ]
for field in file_list_fields :
to_remove = { e : None for e in getattr ( b . cc_file_list , field ) . to_list ( ) }
cc_file_list_args [ field ] = depset (
[ e for e in getattr ( a . cc_file_list , field ) . to_list ( ) if not e in to_remove ] ,
)
result_args [ " cc_file_list " ] = CcFileList ( * * cc_file_list_args )
return struct ( * * result_args )
# Implementation for cc_dist_library rule.
def _cc_dist_library_impl ( ctx ) :
cc_toolchain_info = find_cc_toolchain ( ctx )
@ -274,7 +308,7 @@ def _cc_dist_library_impl(ctx):
cc_toolchain = cc_toolchain_info ,
)
inputs = _collect_inputs ( ctx . attr . deps )
inputs = _subtract_files ( _ collect_inputs ( ctx . attr . deps ) , _collect_inputs ( ctx . attr . dist_deps ) )
# For static libraries, build separately with and without pic.
@ -346,20 +380,17 @@ Create libraries suitable for distribution.
This rule creates static and dynamic libraries from the libraries listed in
' deps ' . The resulting libraries are suitable for distributing all of ' deps '
in a single logical library , for example , in an installable binary package .
Only the targets listed in ' deps ' are included in the result ( i . e . , the
output does not include transitive dependencies ) , allowing precise control
over the library boundary .
The result includes all transitive dependencies , excluding those reachable
from ' dist_deps ' or defined in a separate repository ( e . g . Abseil ) .
The outputs of this rule are a dynamic library and a static library . ( If
the build produces both PIC and non - PIC object files , then there is also a
second static library . ) The example below illustrates additional details .
This rule is different from Bazel ' s experimental `shared_cc_library` in
several ways . First , this rule ignores transitive dependencies , which means
that dynamic library dependencies generally need to be specified via
' linkopts ' . Second , this rule produces a static archive library in addition
to the dynamic shared library . Third , this rule is not directly usable as a
C + + dependency ( although the outputs could be used , e . g . , by ` cc_import ` ) .
This rule is different from Bazel ' s experimental `shared_cc_library` in two
ways . First , this rule produces a static archive library in addition to the
dynamic shared library . Second , this rule is not directly usable as a C + +
dependency ( although the outputs could be used , e . g . , by ` cc_import ` ) .
Example :
@ -372,15 +403,18 @@ Example:
cc_dist_library (
name = " dist " ,
linkopts = [ " -la " ] , # libdist.so dynamically links against liba.so.
deps = [ " :b " , " :c " ] , # Output contains b.o and c.o, but not a .o.
deps = [ " :b " , " :c " ] , # Output contains a.o, b.o, and c.o.
)
""" ,
attrs = {
" deps " : attr . label_list (
doc = ( " The list of libraries to be included in the outputs. " +
" Only these targets ' compilation outputs will be " +
" included (i.e., the transitive dependencies are not " +
" included in the output). " ) ,
doc = ( " The list of libraries to be included in the outputs, " +
" along with their transitive dependencies. " ) ,
aspects = [ cc_file_list_aspect ] ,
) ,
" dist_deps " : attr . label_list (
doc = ( " The list of cc_dist_library dependencies that " +
" should be excluded. " ) ,
aspects = [ cc_file_list_aspect ] ,
) ,
" linkopts " : attr . string_list (