1load(":cc_library_static.bzl", "cc_library_static") 2load("@rules_cc//examples:experimental_cc_shared_library.bzl", "CcSharedLibraryInfo", "cc_shared_library") 3 4def cc_library( 5 name, 6 # attributes for both targets 7 srcs = [], 8 hdrs = [], 9 deps = [], 10 whole_archive_deps = [], 11 dynamic_deps = [], 12 copts = [], 13 includes = [], 14 linkopts = [], 15 # attributes for the shared target 16 dynamic_deps_for_shared = [], 17 shared_copts = [], 18 shared_srcs = [], 19 static_deps_for_shared = [], 20 whole_archive_deps_for_shared = [], 21 user_link_flags = [], 22 version_script = None, 23 # attributes for the static target 24 dynamic_deps_for_static = [], 25 static_copts = [], 26 static_srcs = [], 27 static_deps_for_static = [], 28 whole_archive_deps_for_static = [], 29 **kwargs): 30 static_name = name + "_bp2build_cc_library_static" 31 shared_name = name + "_bp2build_cc_library_shared" 32 shared_root_name = name + "_bp2build_cc_library_shared_root" 33 _cc_library_proxy( 34 name = name, 35 static = static_name, 36 shared = shared_name, 37 ) 38 39 # The static version of the library. 40 cc_library_static( 41 name = static_name, 42 hdrs = hdrs, 43 srcs = srcs + static_srcs, 44 copts = copts + static_copts, 45 includes = includes, 46 linkopts = linkopts, 47 # TODO(b/187533117): Handle whole_archive_deps differently than other deps. 48 deps = deps + static_deps_for_static + whole_archive_deps + whole_archive_deps_for_static, 49 # TODO(b/187746106): Handle dynamic_deps_for_static. 50 ) 51 52 # The static library at the root of the shared library. 53 # This may be distinct from the static library if, for example, 54 # the static-variant srcs are different than the shared-variant srcs. 55 cc_library_static( 56 name = shared_root_name, 57 hdrs = hdrs, 58 srcs = srcs + shared_srcs, 59 copts = copts + shared_copts, 60 includes = includes, 61 linkopts = linkopts, 62 deps = deps + static_deps_for_shared + whole_archive_deps + whole_archive_deps_for_shared, 63 ) 64 65 cc_shared_library( 66 name = shared_name, 67 user_link_flags = user_link_flags, 68 # b/184806113: Note this is a pretty a workaround so users don't have to 69 # declare all transitive static deps used by this target. It'd be great 70 # if a shared library could declare a transitive exported static dep 71 # instead of needing to declare each target transitively. 72 static_deps = ["//:__subpackages__"] + [shared_root_name], 73 dynamic_deps = dynamic_deps + dynamic_deps_for_shared, 74 version_script = version_script, 75 roots = [shared_root_name] + whole_archive_deps + whole_archive_deps_for_shared, 76 ) 77 78def _cc_library_proxy_impl(ctx): 79 static_files = ctx.attr.static[DefaultInfo].files.to_list() 80 shared_files = ctx.attr.shared[DefaultInfo].files.to_list() 81 82 files = static_files + shared_files 83 84 return [ 85 ctx.attr.shared[CcSharedLibraryInfo], 86 ctx.attr.static[CcInfo], 87 DefaultInfo( 88 files = depset(direct = files), 89 runfiles = ctx.runfiles(files = files), 90 ), 91 ] 92 93_cc_library_proxy = rule( 94 implementation = _cc_library_proxy_impl, 95 attrs = { 96 "shared": attr.label(mandatory = True, providers = [CcSharedLibraryInfo]), 97 "static": attr.label(mandatory = True, providers = [CcInfo]), 98 }, 99) 100