-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
Copy pathseparate_debug.bzl
683 lines (606 loc) · 28.8 KB
/
separate_debug.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
TagInfo = provider(
doc = "A rule provider to pass around tags that were passed to rules.",
fields = {
"tags": "Bazel tags that were attached to the rule.",
},
)
WITH_DEBUG_SUFFIX = "_with_debug"
CC_SHARED_LIBRARY_SUFFIX = "_shared"
SHARED_ARCHIVE_SUFFIX = "_shared_archive"
MAC_DEBUG_FOLDER_EXTENSION = ".dSYM"
def get_inputs_and_outputs(ctx, shared_ext, static_ext, debug_ext):
"""
Determines and generates the inputs and outputs.
Inputs are the extensions for shared libraries, static libraries, and debug files for a given platform.
Outputs are:
input_bin: the shared or program binary that contains debug info
Note it is possible this a static library build in which case input_bin can be None
output_bin: The output shared or program binary with the debug info to be stripped
Note it is possible this a static library build in which case output_bin can be None
Note if separate_debug is disabled this will just be a symlink which still contains the debug info
debug_info: If this is a separate_debug build, this will be the output file which will be the extracted debug info
static_lib: The static library if this build is building static libraries. This will be a symlink
"""
shared_lib = None
static_lib = None
input_files = ctx.attr.binary_with_debug.files.to_list()
if len(input_files) == 0:
return None, None, None, None
if ctx.attr.type == "library":
for file in ctx.attr.binary_with_debug.files.to_list():
if file.path.endswith(WITH_DEBUG_SUFFIX + static_ext):
static_lib = file
if ctx.attr.cc_shared_library != None:
for file in ctx.attr.cc_shared_library.files.to_list():
if file.path.endswith(WITH_DEBUG_SUFFIX + shared_ext):
shared_lib = file
if shared_lib:
basename = shared_lib.basename[:-len(WITH_DEBUG_SUFFIX + shared_ext + CC_SHARED_LIBRARY_SUFFIX)]
if ctx.attr.enabled:
if debug_ext == MAC_DEBUG_FOLDER_EXTENSION:
debug_info = ctx.actions.declare_directory(basename + shared_ext + debug_ext)
else:
debug_info = ctx.actions.declare_file(basename + shared_ext + debug_ext)
else:
debug_info = None
output_bin = ctx.actions.declare_file(basename + shared_ext)
input_bin = shared_lib
else:
debug_info = None
output_bin = None
input_bin = None
elif ctx.attr.type == "program":
program_bin = ctx.attr.binary_with_debug.files.to_list()[0]
basename = program_bin.basename[:-len(WITH_DEBUG_SUFFIX)]
if ctx.attr.enabled:
if debug_ext == MAC_DEBUG_FOLDER_EXTENSION:
debug_info = ctx.actions.declare_directory(basename + debug_ext)
else:
debug_info = ctx.actions.declare_file(basename + debug_ext)
else:
debug_info = None
output_bin = ctx.actions.declare_file(basename)
input_bin = program_bin
else:
fail("Can't extract debug info from unknown type: " + ctx.attr.type)
return input_bin, output_bin, debug_info, static_lib
def propgate_static_lib(ctx, static_lib, static_ext, inputs):
"""
Static libraries will not have debug info extracts so we symlink to the new target name.
"""
basename = static_lib.basename[:-len(WITH_DEBUG_SUFFIX + static_ext)]
unstripped_static_lib = ctx.actions.declare_file(basename + static_ext)
ctx.actions.symlink(
output = unstripped_static_lib,
target_file = static_lib,
)
return unstripped_static_lib
def get_transitive_dyn_libs(deps):
"""
Get a transitive list of all dynamic library files under a set of dependencies.
"""
# TODO(SERVER-85819): Investigate to see if it's possible to merge the depset without looping over all transitive
# dependencies.
transitive_dyn_libs = []
for dep in deps:
for input in dep[CcInfo].linking_context.linker_inputs.to_list():
for library in input.libraries:
if library.dynamic_library:
transitive_dyn_libs.append(library.dynamic_library)
return transitive_dyn_libs
def get_transitive_debug_files(deps):
"""
Get a transitive list of all dynamic library files under a set of dependencies.
"""
# TODO(SERVER-85819): Investigate to see if it's possible to merge the depset without looping over all transitive
# dependencies.
transitive_debugs = []
for dep in deps:
for input in dep[DefaultInfo].files.to_list():
if input.basename.endswith(".debug"):
transitive_debugs.append(input)
return transitive_debugs
def symlink_shared_archive(ctx, shared_ext, static_ext):
"""
Shared archives (.so.a/.dll.lib) have different extensions depending on the operating system.
Strip the suffix added on by the target rule and replace the static library ext with the shared archive
ext.
"""
original_output = ctx.attr.shared_archive.files.to_list()[0]
basename = original_output.basename[:-len(SHARED_ARCHIVE_SUFFIX + static_ext)]
symlink = ctx.actions.declare_file(basename + shared_ext + static_ext)
ctx.actions.symlink(
output = symlink,
target_file = original_output,
)
return symlink
def create_new_ccinfo_library(ctx, cc_toolchain, shared_lib, static_lib, cc_shared_library = None):
"""
We need to create new CcInfo with the new target names, this will take in the newly
named library files and construct a new CcInfo basically stripping out the "_with_debug"
name.
"""
if ctx.attr.type == "library":
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
linker_input_deps = []
for dep in ctx.attr.deps:
linker_input_deps.append(dep[CcInfo].linking_context.linker_inputs)
if shared_lib or static_lib:
if shared_lib:
so_path = shared_lib.path.replace(ctx.bin_dir.path + "/", "")
else:
so_path = ""
direct_lib = cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
dynamic_library = shared_lib,
dynamic_library_symlink_path = so_path,
static_library = static_lib if cc_shared_library == None else None,
alwayslink = True,
)
# For some reason Bazel isn't deduplicating the user link flags, which leads to them accumulating
# with each layer added. Deduplicate them manually.
#
# This routine works by taking the current library's link args and searching for each of its dependency's link
# args present contiguously. If a matching sub list is found, it's removed from the current link line as a duplicate.
# This is to avoid removing positional arguments that may appear more than once.
#
# This solution may break in the case where a base dependency contains only one positional argument,
# but this should never happen since we will always inject at least one non positional argument globally.
cur_flags = ctx.attr.binary_with_debug[CcInfo].linking_context.linker_inputs.to_list()[0].user_link_flags
for dep in ctx.attr.binary_with_debug[CcInfo].linking_context.linker_inputs.to_list()[1:]:
for i in range(len(cur_flags)):
dep_flags = dep.user_link_flags
if dep_flags and cur_flags:
if cur_flags[i] == dep_flags[0] and cur_flags[i:i + len(dep_flags)] == dep_flags:
cur_flags = cur_flags[:i] + cur_flags[i + len(dep_flags):]
break
linker_input = cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(direct = [direct_lib]),
user_link_flags = cur_flags,
)
linking_context = cc_common.create_linking_context(linker_inputs = depset(direct = [linker_input], transitive = linker_input_deps))
else:
linking_context = cc_common.create_linking_context(linker_inputs = depset(transitive = linker_input_deps))
else:
linking_context = ctx.attr.binary_with_debug[CcInfo].linking_context
return CcInfo(
compilation_context = ctx.attr.binary_with_debug[CcInfo].compilation_context,
linking_context = linking_context,
)
def create_new_cc_shared_library_info(ctx, cc_toolchain, output_shared_lib, original_info, static_lib = None):
"""
We need to create a CcSharedLibraryInfo to pass to the cc_binary and cc_library that depend on it
so they know to link the cc_shared_library instead of the associated cc_library.
name.
"""
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
# Loop through all dependencies to include their resulting (shared/debug decorator stripped) shared library files
# as inputs.
# TODO(SERVER-85819): Investigate to see if it's possible to merge the depset without looping over all transitive
# dependencies.
dep_libraries = []
for dep in ctx.attr.deps:
for input in dep[CcInfo].linking_context.linker_inputs.to_list():
for library in input.libraries:
dep_libraries.append(library)
# CcInfo's linkopts are ignored by cc_shared_library by default. To support both transitive and nontransitive
# dynamic linkopts use:
# cc_library's linkopts field for both static and dynamic transitive link opts
# cc_shared_library's user_link_flags field for dynamic non-transitive link opts
all_user_link_flags = dict()
for input in ctx.attr.binary_with_debug[CcInfo].linking_context.linker_inputs.to_list():
for flag in input.user_link_flags:
all_user_link_flags[flag] = True
# We define global linkopts here too, remove duplicates to prevent repeats of the global opts
# from accumulating.
for flag in original_info.linker_input.user_link_flags:
all_user_link_flags[flag] = True
all_user_link_flags = [flag for flag, _ in all_user_link_flags.items()]
if output_shared_lib:
direct_lib = cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
# Replace reference to dynamic library with final name
dynamic_library = output_shared_lib,
dynamic_library_symlink_path = output_shared_lib.path.replace(ctx.bin_dir.path + "/", ""),
# Omit reference to static library
)
linker_input = cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(direct = [direct_lib], transitive = [depset(dep_libraries)]),
user_link_flags = all_user_link_flags,
additional_inputs = depset(original_info.linker_input.additional_inputs),
)
else:
linker_input = cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(transitive = [depset(dep_libraries)]),
user_link_flags = all_user_link_flags,
additional_inputs = depset(original_info.linker_input.additional_inputs),
)
return CcSharedLibraryInfo(
dynamic_deps = original_info.dynamic_deps,
exports = original_info.exports,
link_once_static_libs = original_info.link_once_static_libs,
linker_input = linker_input,
)
# TODO(SERVER-101906): We assume the worst-case resource usage to avoid OOMs. Figure out if we can
# generalize numInputs for all link configurations so that this can more intelligently set resource
# expectations.
def linux_extract_resource_set(os, numInputs):
return {
"cpu": 6,
"memory": 20 * 1024, # 20 GB
"local_test": 1,
}
def linux_strip_resource_set(os, numInputs):
return {
"cpu": 3,
"memory": 10 * 1024, # 10 GB
"local_test": 1,
}
def linux_extraction(ctx, cc_toolchain, inputs):
outputs = []
unstripped_static_bin = None
input_bin, output_bin, debug_info, static_lib = get_inputs_and_outputs(ctx, ".so", ".a", ".debug")
input_file = ctx.attr.binary_with_debug.files.to_list()
if input_bin:
if ctx.attr.enabled:
ctx.actions.run(
executable = cc_toolchain.objcopy_executable,
outputs = [debug_info],
inputs = inputs,
resource_set = linux_extract_resource_set if ctx.attr.type == "program" else None,
arguments = [
"--only-keep-debug",
input_bin.path,
debug_info.path,
],
mnemonic = "ExtractDebuginfo",
)
ctx.actions.run(
executable = cc_toolchain.objcopy_executable,
outputs = [output_bin],
inputs = depset([debug_info], transitive = [inputs]),
resource_set = linux_strip_resource_set if ctx.attr.type == "program" else None,
arguments = [
"--strip-debug",
"--add-gnu-debuglink",
debug_info.path,
input_bin.path,
output_bin.path,
],
mnemonic = "StripDebuginfo",
)
outputs += [output_bin, debug_info]
else:
ctx.actions.symlink(
output = output_bin,
target_file = input_bin,
)
outputs += [output_bin]
if len(input_file):
if static_lib:
unstripped_static_bin = propgate_static_lib(ctx, static_lib, ".a", inputs)
outputs.append(unstripped_static_bin)
if ctx.attr.shared_archive:
unstripped_shared_archive = symlink_shared_archive(ctx, ".so", ".a")
outputs.append(unstripped_shared_archive)
# The final program binary depends on the existence of the dependent dynamic library files. With
# build-without-the-bytes enabled, these aren't downloaded. Manually collect them and add them to the
# output set.
dynamic_deps_runfiles = ctx.runfiles(files = [])
if ctx.attr.type == "program":
dynamic_deps = get_transitive_dyn_libs(ctx.attr.deps)
dynamic_deps_runfiles = ctx.attr.binary_with_debug[DefaultInfo].data_runfiles.merge(ctx.runfiles(files = get_transitive_dyn_libs(ctx.attr.deps)))
outputs.extend(dynamic_deps)
provided_info = [
DefaultInfo(
files = depset(outputs, transitive = [depset(get_transitive_debug_files(ctx.attr.deps))]),
runfiles = dynamic_deps_runfiles,
executable = output_bin if ctx.attr.type == "program" else None,
),
create_new_ccinfo_library(ctx, cc_toolchain, output_bin, unstripped_static_bin, ctx.attr.cc_shared_library),
]
if ctx.attr.type == "program":
provided_info += [
RunEnvironmentInfo(
environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].environment,
inherited_environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].inherited_environment,
),
]
provided_info += [ctx.attr.binary_with_debug[DebugPackageInfo]]
if ctx.attr.cc_shared_library != None:
provided_info.append(
create_new_cc_shared_library_info(ctx, cc_toolchain, output_bin, ctx.attr.cc_shared_library[CcSharedLibraryInfo], static_lib),
)
return provided_info
def macos_extraction(ctx, cc_toolchain, inputs):
outputs = []
unstripped_static_bin = None
input_bin, output_bin, debug_info, static_lib = get_inputs_and_outputs(ctx, ".dylib", ".a", MAC_DEBUG_FOLDER_EXTENSION)
input_file = ctx.attr.binary_with_debug.files.to_list()
if input_bin:
if ctx.attr.enabled:
ctx.actions.run(
executable = "dsymutil",
outputs = [debug_info],
inputs = inputs,
arguments = [
"-num-threads",
"1",
input_bin.path,
"-o",
debug_info.path,
],
mnemonic = "ExtractDebuginfo",
)
ctx.actions.run(
executable = cc_toolchain.strip_executable,
outputs = [output_bin],
inputs = depset([debug_info], transitive = [inputs]),
arguments = [
"-S",
"-o",
output_bin.path,
input_bin.path,
],
mnemonic = "StripDebuginfo",
)
outputs += [output_bin, debug_info]
else:
ctx.actions.symlink(
output = output_bin,
target_file = input_bin,
)
outputs += [output_bin]
if len(input_file):
if static_lib:
unstripped_static_bin = propgate_static_lib(ctx, static_lib, ".a", inputs)
outputs.append(unstripped_static_bin)
if ctx.attr.shared_archive:
unstripped_shared_archive = symlink_shared_archive(ctx, ".dylib", ".a")
outputs.append(unstripped_shared_archive)
# The final program binary depends on the existence of the dependent dynamic library files. With
# build-without-the-bytes enabled, these aren't downloaded. Manually collect them and add them to the
# output set.
dynamic_deps_runfiles = ctx.runfiles(files = [])
if ctx.attr.type == "program":
dynamic_deps = get_transitive_dyn_libs(ctx.attr.deps)
dynamic_deps_runfiles = ctx.attr.binary_with_debug[DefaultInfo].data_runfiles.merge(ctx.runfiles(files = get_transitive_dyn_libs(ctx.attr.deps)))
outputs.extend(dynamic_deps)
provided_info = [
DefaultInfo(
files = depset(outputs),
executable = output_bin if ctx.attr.type == "program" else None,
runfiles = ctx.attr.binary_with_debug[DefaultInfo].data_runfiles,
),
create_new_ccinfo_library(ctx, cc_toolchain, output_bin, unstripped_static_bin, ctx.attr.cc_shared_library),
]
if ctx.attr.type == "program":
provided_info += [
RunEnvironmentInfo(
environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].environment,
inherited_environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].inherited_environment,
),
]
if ctx.attr.cc_shared_library != None:
provided_info.append(
create_new_cc_shared_library_info(ctx, cc_toolchain, output_bin, ctx.attr.cc_shared_library[CcSharedLibraryInfo]),
)
return provided_info
def windows_extraction(ctx, cc_toolchain, inputs):
pdb = None
if ctx.attr.type == "library":
ext = ".lib"
if ctx.attr.cc_shared_library and ctx.attr.enable_pdb:
pdb = ctx.attr.cc_shared_library[OutputGroupInfo].pdb_file
elif ctx.attr.type == "program":
ext = ".exe"
if ctx.attr.enable_pdb:
pdb = ctx.attr.binary_with_debug[OutputGroupInfo].pdb_file
else:
fail("Can't extract debug info from unknown type: " + ctx.attr.type)
input_file = ctx.attr.binary_with_debug.files.to_list()
outputs = []
output_library = None
output_dynamic_library = None
if len(input_file):
basename = ctx.attr.binary_with_debug.files.to_list()[0].basename[:-len(WITH_DEBUG_SUFFIX + ext)]
output = ctx.actions.declare_file(basename + ext)
for input in ctx.attr.binary_with_debug.files.to_list():
ext = "." + input.extension
basename = input.basename[:-len(WITH_DEBUG_SUFFIX + ext)]
output = ctx.actions.declare_file(basename + ext)
outputs.append(output)
if ext == ".lib":
output_library = output
ctx.actions.symlink(
output = output,
target_file = input,
)
if ctx.attr.cc_shared_library != None:
for file in ctx.attr.cc_shared_library.files.to_list():
if file.path.endswith(".dll"):
basename = file.basename[:-len(WITH_DEBUG_SUFFIX + CC_SHARED_LIBRARY_SUFFIX + ".dll")]
output = ctx.actions.declare_file(basename + ".dll")
outputs.append(output)
output_dynamic_library = output
ctx.actions.symlink(
output = output,
target_file = file,
)
if pdb:
if ctx.attr.cc_shared_library != None:
basename = input.basename[:-len(WITH_DEBUG_SUFFIX + ".pdb")]
pdb_output = ctx.actions.declare_file(basename + ".dll.pdb")
else:
basename = input.basename[:-len(WITH_DEBUG_SUFFIX + ext)]
pdb_output = ctx.actions.declare_file(basename + ".pdb")
outputs.append(pdb_output)
ctx.actions.symlink(
output = pdb_output,
target_file = pdb.to_list()[0],
)
if ctx.attr.shared_archive:
unstripped_shared_archive = symlink_shared_archive(ctx, ".dll", ".lib")
outputs.append(unstripped_shared_archive)
provided_info = [
DefaultInfo(
files = depset(outputs),
executable = output if ctx.attr.type == "program" else None,
runfiles = ctx.attr.binary_with_debug[DefaultInfo].data_runfiles,
),
create_new_ccinfo_library(ctx, cc_toolchain, output_dynamic_library, output_library, ctx.attr.cc_shared_library),
]
if ctx.attr.type == "program":
provided_info += [
RunEnvironmentInfo(
environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].environment,
inherited_environment = ctx.attr.binary_with_debug[RunEnvironmentInfo].inherited_environment,
),
]
if ctx.attr.cc_shared_library != None:
provided_info.append(
create_new_cc_shared_library_info(ctx, cc_toolchain, output_dynamic_library, ctx.attr.cc_shared_library[CcSharedLibraryInfo]),
)
return provided_info
def extract_debuginfo_impl(ctx):
cc_toolchain = find_cpp_toolchain(ctx)
inputs = depset(transitive = [
ctx.attr.binary_with_debug.files,
ctx.attr.cc_shared_library.files if ctx.attr.cc_shared_library != None else depset([]),
cc_toolchain.all_files,
])
linux_constraint = ctx.attr._linux_constraint[platform_common.ConstraintValueInfo]
macos_constraint = ctx.attr._macos_constraint[platform_common.ConstraintValueInfo]
windows_constraint = ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]
if ctx.target_platform_has_constraint(linux_constraint):
# When skipping the archives we have to skip modifying debug info
# for the intermediates because we end up taking a dependency
# on the _with_debug .a files
if ctx.attr.skip_archive and ctx.attr.cc_shared_library == None:
return_info = [ctx.attr.binary_with_debug[CcInfo]]
else:
return_info = linux_extraction(ctx, cc_toolchain, inputs)
elif ctx.target_platform_has_constraint(macos_constraint):
if ctx.attr.skip_archive and ctx.attr.cc_shared_library == None:
return_info = [ctx.attr.binary_with_debug[CcInfo]]
else:
return_info = macos_extraction(ctx, cc_toolchain, inputs)
elif ctx.target_platform_has_constraint(windows_constraint):
return_info = windows_extraction(ctx, cc_toolchain, inputs)
tag_provider = TagInfo(tags = ctx.attr.tags)
return_info.append(tag_provider)
return return_info
extract_debuginfo = rule(
extract_debuginfo_impl,
attrs = {
"binary_with_debug": attr.label(
doc = "The the binary to extract debuginfo from.",
allow_files = True,
),
"type": attr.string(
doc = "Set to either 'library' or 'program' to discern how to extract the info.",
),
"enabled": attr.bool(default = False, doc = "Flag to enable/disable separate debug generation."),
"enable_pdb": attr.bool(default = False, doc = "Flag to enable pdb outputs on windows."),
"deps": attr.label_list(providers = [CcInfo]),
"cc_shared_library": attr.label(
doc = "If extracting from a shared library, the target of the cc_shared_library. Otherwise empty.",
allow_files = True,
),
"shared_archive": attr.label(
doc = "If generating a shared archive(.so.a/.dll.lib), the shared archive's cc_library. Otherwise empty.",
allow_files = True,
),
"skip_archive": attr.bool(default = False, doc = "Flag to skip generating archives."),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
"_linux_constraint": attr.label(default = "@platforms//os:linux"),
"_macos_constraint": attr.label(default = "@platforms//os:macos"),
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
},
doc = "Extract debuginfo into a separate file",
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
)
extract_debuginfo_binary = rule(
extract_debuginfo_impl,
attrs = {
"binary_with_debug": attr.label(
doc = "The the binary to extract debuginfo from.",
allow_files = True,
),
"type": attr.string(
doc = "Set to either 'library' or 'program' to discern how to extract the info.",
),
"enabled": attr.bool(default = False, doc = "Flag to enable/disable separate debug generation."),
"enable_pdb": attr.bool(default = False, doc = "Flag to enable pdb outputs on windows."),
"deps": attr.label_list(providers = [CcInfo]),
"cc_shared_library": attr.label(
doc = "If extracting from a shared library, the target of the cc_shared_library. Otherwise empty.",
allow_files = True,
),
"shared_archive": attr.label(
doc = "If generating a shared archive(.so.a/.dll.lib), the shared archive's cc_library. Otherwise empty.",
allow_files = True,
),
"skip_archive": attr.bool(default = False, doc = "Flag to skip generating archives."),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
"_linux_constraint": attr.label(default = "@platforms//os:linux"),
"_macos_constraint": attr.label(default = "@platforms//os:macos"),
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
},
doc = "Extract debuginfo into a separate file",
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
executable = True,
)
extract_debuginfo_test = rule(
extract_debuginfo_impl,
attrs = {
"binary_with_debug": attr.label(
doc = "The the binary to extract debuginfo from.",
allow_files = True,
),
"type": attr.string(
doc = "Set to either 'library' or 'program' to discern how to extract the info.",
),
"enabled": attr.bool(default = False, doc = "Flag to enable/disable separate debug generation."),
"enable_pdb": attr.bool(default = False, doc = "Flag to enable pdb outputs on windows."),
"deps": attr.label_list(providers = [CcInfo]),
"cc_shared_library": attr.label(
doc = "If extracting from a shared library, the target of the cc_shared_library. Otherwise empty.",
allow_files = True,
),
"shared_archive": attr.label(
doc = "If generating a shared archive(.so.a/.dll.lib), the shared archive's cc_library. Otherwise empty.",
allow_files = True,
),
"skip_archive": attr.bool(default = False, doc = "Flag to skip generating archives."),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
"_linux_constraint": attr.label(default = "@platforms//os:linux"),
"_macos_constraint": attr.label(default = "@platforms//os:macos"),
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
},
doc = "Extract debuginfo into a separate file",
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
executable = True,
test = True,
)