Skip to content

Commit b800f37

Browse files
committed
cc_binary: support .dSYM generation
Add support for generating a .dSYM file if this is requested using `--apple_generate_dsym`. This change contains the following patches: * Add `-fdebug-prefix-map` and `-oso_prefix` compiler and linker flags as in more recent Xcode versions (16E140) it would cause sandbox paths leaking into the linked binaries. * Add `DSYM_HINT` flags to be picked up by `wrapped_clang` to generate .dSYM bundles on request. * In `wrapped_clang.cc` make sure the linked binary is stripped after generating the .dSYM bundle first to make the .dSYM bundle contain useful information. Adopts recent changes in bazel to support .dSYM files (as part of fixing bazelbuild/bazel#16893).
1 parent e6334b7 commit b800f37

File tree

3 files changed

+53
-17
lines changed

3 files changed

+53
-17
lines changed

crosstool/cc_toolchain_config.bzl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ please file an issue at https://github.com/bazelbuild/apple_support/issues/new
861861
actions = _DYNAMIC_LINK_ACTIONS,
862862
flag_groups = [
863863
flag_group(
864-
flags = ["-Wl,-S"],
864+
flags = ["STRIP_DEBUG_SYMBOLS"],
865865
expand_if_available = "strip_debug_symbols",
866866
),
867867
],
@@ -2059,13 +2059,14 @@ please file an issue at https://github.com/bazelbuild/apple_support/issues/new
20592059
flag_groups = [flag_group(flags = ["-g"])],
20602060
),
20612061
flag_set(
2062-
actions = ["objc-executable"],
2062+
actions = _DYNAMIC_LINK_ACTIONS,
20632063
flag_groups = [
20642064
flag_group(
20652065
flags = [
2066-
"DSYM_HINT_LINKED_BINARY=%{linked_binary}",
2066+
"DSYM_HINT_LINKED_BINARY=%{output_execpath}",
20672067
"DSYM_HINT_DSYM_PATH=%{dsym_path}",
20682068
],
2069+
expand_if_available = "output_execpath",
20692070
),
20702071
],
20712072
),

crosstool/wrapped_clang.cc

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,15 @@ void ProcessArgument(const std::string arg, const std::string developer_dir,
261261
const std::string sdk_root, const std::string cwd,
262262
const std::string nosandbox_root, bool relative_ast_path,
263263
std::string &linked_binary, std::string &dsym_path,
264-
std::string toolchain_path,
264+
bool &strip_debug_symbols, std::string toolchain_path,
265265
std::function<void(const std::string &)> consumer);
266266

267267
bool ProcessResponseFile(const std::string arg, const std::string developer_dir,
268268
const std::string sdk_root, const std::string cwd,
269269
const std::string nosandbox_root,
270270
bool relative_ast_path, std::string &linked_binary,
271-
std::string &dsym_path, std::string toolchain_path,
271+
std::string &dsym_path, bool &strip_debug_symbols,
272+
std::string toolchain_path,
272273
std::function<void(const std::string &)> consumer) {
273274
auto path = arg.substr(1);
274275
std::ifstream original_file(path);
@@ -283,7 +284,7 @@ bool ProcessResponseFile(const std::string arg, const std::string developer_dir,
283284
// unescape them ourselves.
284285
ProcessArgument(Unescape(arg_from_file), developer_dir, sdk_root, cwd,
285286
nosandbox_root, relative_ast_path, linked_binary, dsym_path,
286-
toolchain_path, consumer);
287+
strip_debug_symbols, toolchain_path, consumer);
287288
}
288289

289290
return true;
@@ -341,13 +342,13 @@ void ProcessArgument(const std::string arg, const std::string developer_dir,
341342
const std::string sdk_root, const std::string cwd,
342343
const std::string nosandbox_root, bool relative_ast_path,
343344
std::string &linked_binary, std::string &dsym_path,
344-
std::string toolchain_path,
345+
bool &strip_debug_symbols, std::string toolchain_path,
345346
std::function<void(const std::string &)> consumer) {
346347
auto new_arg = arg;
347348
if (arg[0] == '@') {
348349
if (ProcessResponseFile(arg, developer_dir, sdk_root, cwd, nosandbox_root,
349350
relative_ast_path, linked_binary, dsym_path,
350-
toolchain_path, consumer)) {
351+
strip_debug_symbols, toolchain_path, consumer)) {
351352
return;
352353
}
353354
}
@@ -358,6 +359,10 @@ void ProcessArgument(const std::string arg, const std::string developer_dir,
358359
if (SetArgIfFlagPresent(arg, "DSYM_HINT_DSYM_PATH", &dsym_path)) {
359360
return;
360361
}
362+
if (arg == "STRIP_DEBUG_SYMBOLS") {
363+
strip_debug_symbols = true;
364+
return;
365+
}
361366

362367
FindAndReplace("__BAZEL_EXECUTION_ROOT__", cwd, &new_arg);
363368
FindAndReplace("__BAZEL_EXECUTION_ROOT_NO_SANDBOX__", nosandbox_root,
@@ -427,6 +432,7 @@ int main(int argc, char *argv[]) {
427432
std::string developer_dir = GetMandatoryEnvVar("DEVELOPER_DIR");
428433
std::string sdk_root = GetMandatoryEnvVar("SDKROOT");
429434
std::string linked_binary, dsym_path;
435+
bool strip_debug_symbols = false;
430436

431437
const std::string cwd = GetCurrentDirectory();
432438
std::vector<std::string> invocation_args = {"/usr/bin/xcrun", tool_name};
@@ -453,8 +459,8 @@ int main(int argc, char *argv[]) {
453459
std::string arg(argv[i]);
454460

455461
ProcessArgument(arg, developer_dir, sdk_root, cwd, nosandbox_root,
456-
relative_ast_path, linked_binary, dsym_path, toolchain_path,
457-
consumer);
462+
relative_ast_path, linked_binary, dsym_path,
463+
strip_debug_symbols, toolchain_path, consumer);
458464
}
459465

460466
char *modulemap = getenv("APPLE_SUPPORT_MODULEMAP");
@@ -509,16 +515,32 @@ int main(int argc, char *argv[]) {
509515
return 0;
510516
}
511517

512-
std::vector<std::string> dsymutil_args = {"/usr/bin/xcrun",
513-
"dsymutil",
514-
linked_binary,
515-
"-o",
516-
dsym_path,
517-
"--flat",
518-
"--no-swiftmodule-timestamp"};
518+
const std::string bundle_suffix = ".dSYM";
519+
bool is_bundle = dsym_path.rfind(bundle_suffix) ==
520+
dsym_path.length() - bundle_suffix.length();
521+
522+
std::vector<std::string> dsymutil_args = {
523+
"/usr/bin/xcrun", "dsymutil",
524+
linked_binary, "-o",
525+
dsym_path, "--no-swiftmodule-timestamp"};
526+
if (!is_bundle) {
527+
// We should generate a .dSYM bundle only when a path is passed to a .dSYM
528+
// directory for backwards compatibility
529+
dsymutil_args.push_back("--flat");
530+
}
519531
if (!RunSubProcess(dsymutil_args)) {
520532
return 1;
521533
}
522534

535+
// When stripping is requested, we should still strip the binary
536+
// before returning
537+
if (strip_debug_symbols) {
538+
std::vector<std::string> strip_args = {"/usr/bin/xcrun", "strip", "-S",
539+
linked_binary};
540+
if (!RunSubProcess(strip_args)) {
541+
return 2;
542+
}
543+
}
544+
523545
return 0;
524546
}

test/linking_tests.bzl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,16 @@ def linking_test_suite(name):
187187
mnemonic = "ObjcLink",
188188
target_under_test = "//test/test_data:macos_binary",
189189
)
190+
191+
dsym_test(
192+
name = "{}_generate_cpp_dsym_test".format(name),
193+
tags = [name] +
194+
# Can't be enabled until https://github.com/bazelbuild/bazel/pull/25881 lands
195+
["manual"],
196+
expected_argv = [
197+
"DSYM_HINT_LINKED_BINARY",
198+
"DSYM_HINT_DSYM_PATH",
199+
],
200+
mnemonic = "CppLink",
201+
target_under_test = "//test/test_data:cc_test_binary",
202+
)

0 commit comments

Comments
 (0)