@@ -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+
4375def _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 ,
0 commit comments