Skip to content

Commit c657db8

Browse files
authored
Add cc_static_library rule [BUILD-542] (#50)
* Add cc_static_library rule * Move filter to rules_swiftnav * Add workaround for older archiver * Move cc_static_library to /cc
1 parent f9335d1 commit c657db8

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

cc/cc_static_library.bzl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
2+
3+
def _get_linker_inputs(deps):
4+
lib_sets = []
5+
for dep in deps:
6+
lib_sets.append(dep[CcInfo].linking_context.linker_inputs)
7+
input_depset = depset(transitive = lib_sets)
8+
return input_depset.to_list()
9+
10+
def _get_static_libaries(ctx, lib):
11+
# This statement checks if path contains "+" and replaces it with "_".
12+
# This workaround is needed for the older version of archiver (2.31.1), which doesn't accept paths with "+".
13+
if lib.path.find("+") != -1:
14+
new_lib = ctx.actions.declare_file(lib.path.replace("+", "_"))
15+
ctx.actions.run_shell(
16+
command = "cp {} {}".format(lib.path, new_lib.path),
17+
inputs = [lib],
18+
outputs = [new_lib],
19+
)
20+
return new_lib
21+
return lib
22+
23+
def _get_libs(ctx, linker_inputs):
24+
libs = []
25+
for inp in linker_inputs:
26+
for lib in inp.libraries:
27+
if lib.pic_static_library:
28+
libs.append(_get_static_libaries(ctx, lib.pic_static_library))
29+
elif lib.static_library:
30+
libs.append(_get_static_libaries(ctx, lib.static_library))
31+
return libs
32+
33+
def _get_commands(output_lib, libs):
34+
commands = ["create {}".format(output_lib.path)]
35+
for lib in libs:
36+
commands.append("addlib {}".format(lib.path))
37+
commands.append("save")
38+
commands.append("end")
39+
return commands
40+
41+
def _cc_static_library_impl(ctx):
42+
output_lib = ctx.actions.declare_file("{}.a".format(ctx.attr.name))
43+
44+
cc_toolchain = find_cpp_toolchain(ctx)
45+
46+
linker_inputs = _get_linker_inputs(ctx.attr.deps)
47+
48+
libs = _get_libs(ctx, linker_inputs)
49+
50+
script_file = ctx.actions.declare_file("{}.mri".format(ctx.attr.name))
51+
ctx.actions.write(
52+
output = script_file,
53+
content = "\n".join(_get_commands(output_lib, libs)) + "\n",
54+
)
55+
56+
ctx.actions.run_shell(
57+
command = "{} -M < {}".format(cc_toolchain.ar_executable, script_file.path),
58+
inputs = [script_file] + libs + cc_toolchain.all_files.to_list(),
59+
outputs = [output_lib],
60+
mnemonic = "ArMerge",
61+
progress_message = "Merging static library {}".format(output_lib.path),
62+
)
63+
return [
64+
DefaultInfo(files = depset([output_lib])),
65+
]
66+
67+
cc_static_library = rule(
68+
implementation = _cc_static_library_impl,
69+
attrs = {
70+
"deps": attr.label_list(),
71+
"_cc_toolchain": attr.label(
72+
default = "@bazel_tools//tools/cpp:current_cc_toolchain",
73+
),
74+
},
75+
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
76+
incompatible_use_toolchain_transition = True,
77+
)

cc/defs.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
load("//tools:stamp_file.bzl", "stamp_file")
1414
load(":utils.bzl", "construct_local_include")
1515
load(":copts.bzl", "DEFAULT_COPTS", "GCC6_COPTS")
16+
load(":cc_static_library.bzl", _cc_static_library = "cc_static_library")
17+
18+
# reexport cc_static_library
19+
cc_static_library = _cc_static_library
1620

1721
# Name for a unit test
1822
UNIT = "unit"

tools/filter.bzl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
def _filter_impl(ctx):
2+
return DefaultInfo(files = depset([f for f in ctx.files.srcs if f.extension == ctx.attr.extension]))
3+
4+
filter = rule(
5+
implementation = _filter_impl,
6+
attrs = {
7+
"srcs": attr.label_list(allow_files = True, mandatory = True),
8+
"extension": attr.string(mandatory = True),
9+
},
10+
)
11+
12+
def filter_srcs(name, srcs):
13+
filter(name = name, srcs = srcs, extension = "c")
14+
15+
def filter_hdrs(name, srcs):
16+
filter(name = name, srcs = srcs, extension = "h")
17+
18+
def filter_libs(name, srcs):
19+
filter(name = name, srcs = srcs, extension = "a")

0 commit comments

Comments
 (0)