Skip to content

Commit 73b468f

Browse files
authored
cc_static_library for mac (#181)
1 parent a56ac00 commit 73b468f

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

cc/cc_static_library.bzl

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,38 @@ def _get_commands(output_lib, libs):
4040
commands.append("end")
4141
return commands
4242

43+
def _run_ar_mri(ctx, cc_toolchain, script_file, output_lib, libs):
44+
ctx.actions.run_shell(
45+
command = "{} -M < {}".format(cc_toolchain.ar_executable, script_file.path),
46+
inputs = [script_file] + libs + cc_toolchain.all_files.to_list(),
47+
outputs = [output_lib],
48+
mnemonic = "ArMerge",
49+
progress_message = "Merging static library {}".format(output_lib.path),
50+
)
51+
52+
def _run_ar_bsd(ctx, cc_toolchain, output_lib, libs):
53+
# macOS uses libtool instead of ar for creating static libraries
54+
args = ctx.actions.args()
55+
if cc_toolchain.ar_executable.endswith("libtool"):
56+
args.add("-static")
57+
args.add("-o")
58+
args.add(output_lib.path)
59+
args.add_all(libs)
60+
else:
61+
# BSD ar doesn't support MRI scripts, so we create the archive manually
62+
args.add("rc") # replace and create
63+
args.add(output_lib.path)
64+
args.add_all(libs)
65+
66+
ctx.actions.run(
67+
executable = cc_toolchain.ar_executable,
68+
arguments = [args],
69+
inputs = libs + cc_toolchain.all_files.to_list(),
70+
outputs = [output_lib],
71+
mnemonic = "ArMerge",
72+
progress_message = "Merging static library {}".format(output_lib.path),
73+
)
74+
4375
def _cc_static_library_impl(ctx):
4476
output_lib = ctx.actions.declare_file("{}.a".format(ctx.attr.name))
4577

@@ -49,19 +81,18 @@ def _cc_static_library_impl(ctx):
4981

5082
libs = _get_libs(ctx, linker_inputs)
5183

52-
script_file = ctx.actions.declare_file("{}.mri".format(ctx.attr.name))
53-
ctx.actions.write(
54-
output = script_file,
55-
content = "\n".join(_get_commands(output_lib, libs)) + "\n",
56-
)
84+
# Use different ar strategies based on platform
85+
# GNU ar supports MRI scripts, BSD ar (macOS) does not
86+
if ctx.target_platform_has_constraint(ctx.attr._macos_constraint[platform_common.ConstraintValueInfo]):
87+
_run_ar_bsd(ctx, cc_toolchain, output_lib, libs)
88+
else:
89+
script_file = ctx.actions.declare_file("{}.mri".format(ctx.attr.name))
90+
ctx.actions.write(
91+
output = script_file,
92+
content = "\n".join(_get_commands(output_lib, libs)) + "\n",
93+
)
94+
_run_ar_mri(ctx, cc_toolchain, script_file, output_lib, libs)
5795

58-
ctx.actions.run_shell(
59-
command = "{} -M < {}".format(cc_toolchain.ar_executable, script_file.path),
60-
inputs = [script_file] + libs + cc_toolchain.all_files.to_list(),
61-
outputs = [output_lib],
62-
mnemonic = "ArMerge",
63-
progress_message = "Merging static library {}".format(output_lib.path),
64-
)
6596
return [
6697
DefaultInfo(files = depset([output_lib])),
6798
]
@@ -73,6 +104,9 @@ cc_static_library = rule(
73104
"_cc_toolchain": attr.label(
74105
default = "@bazel_tools//tools/cpp:current_cc_toolchain",
75106
),
107+
"_macos_constraint": attr.label(
108+
default = "@platforms//os:macos",
109+
),
76110
},
77111
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
78112
incompatible_use_toolchain_transition = True,

cc/defs.bzl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,6 @@ def cc_static_library(name, deps, visibility = ["//visibility:private"]):
195195
_cc_static_library(
196196
name = name,
197197
deps = deps,
198-
target_compatible_with = select({
199-
# Creating static libraries is not supported by macos yet.
200-
"@platforms//os:macos": ["@platforms//:incompatible"],
201-
"//conditions:default": [],
202-
}),
203198
visibility = visibility,
204199
)
205200

0 commit comments

Comments
 (0)