blob: 4a8e7b036a2af95e44a40597814f84df318ce7df [file] [log] [blame]
load(":cc_library_static.bzl", "cc_library_static")
load("@rules_cc//examples:experimental_cc_shared_library.bzl", "CcSharedLibraryInfo", "cc_shared_library")
def cc_library(
name,
# attributes for both targets
srcs = [],
hdrs = [],
deps = [],
whole_archive_deps = [],
dynamic_deps = [],
copts = [],
includes = [],
linkopts = [],
# attributes for the shared target
dynamic_deps_for_shared = [],
shared_copts = [],
shared_srcs = [],
static_deps_for_shared = [],
whole_archive_deps_for_shared = [],
user_link_flags = [],
version_script = None,
# attributes for the static target
dynamic_deps_for_static = [],
static_copts = [],
static_srcs = [],
static_deps_for_static = [],
whole_archive_deps_for_static = [],
**kwargs):
static_name = name + "_bp2build_cc_library_static"
shared_name = name + "_bp2build_cc_library_shared"
shared_root_name = name + "_bp2build_cc_library_shared_root"
_cc_library_proxy(
name = name,
static = static_name,
shared = shared_name,
)
# The static version of the library.
cc_library_static(
name = static_name,
hdrs = hdrs,
srcs = srcs + static_srcs,
copts = copts + static_copts,
includes = includes,
linkopts = linkopts,
# TODO(b/187533117): Handle whole_archive_deps differently than other deps.
deps = deps + static_deps_for_static + whole_archive_deps + whole_archive_deps_for_static,
# TODO(b/187746106): Handle dynamic_deps_for_static.
)
# The static library at the root of the shared library.
# This may be distinct from the static library if, for example,
# the static-variant srcs are different than the shared-variant srcs.
cc_library_static(
name = shared_root_name,
hdrs = hdrs,
srcs = srcs + shared_srcs,
copts = copts + shared_copts,
includes = includes,
linkopts = linkopts,
deps = deps + static_deps_for_shared + whole_archive_deps + whole_archive_deps_for_shared,
)
cc_shared_library(
name = shared_name,
user_link_flags = user_link_flags,
# b/184806113: Note this is a pretty a workaround so users don't have to
# declare all transitive static deps used by this target. It'd be great
# if a shared library could declare a transitive exported static dep
# instead of needing to declare each target transitively.
static_deps = ["//:__subpackages__"] + [shared_root_name],
dynamic_deps = dynamic_deps + dynamic_deps_for_shared,
version_script = version_script,
roots = [shared_root_name] + whole_archive_deps + whole_archive_deps_for_shared,
)
def _cc_library_proxy_impl(ctx):
static_files = ctx.attr.static[DefaultInfo].files.to_list()
shared_files = ctx.attr.shared[DefaultInfo].files.to_list()
files = static_files + shared_files
return [
ctx.attr.shared[CcSharedLibraryInfo],
ctx.attr.static[CcInfo],
DefaultInfo(
files = depset(direct = files),
runfiles = ctx.runfiles(files = files),
),
]
_cc_library_proxy = rule(
implementation = _cc_library_proxy_impl,
attrs = {
"shared": attr.label(mandatory = True, providers = [CcSharedLibraryInfo]),
"static": attr.label(mandatory = True, providers = [CcInfo]),
},
)