• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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