From ba2e0fee2c08294862e85cbd81f8e8cbb2ea377f Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Mon, 27 Oct 2025 11:34:11 -0700 Subject: [PATCH 1/4] [dsymutil] Add option to include swiftmodules built from interface --- llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 6 +++--- llvm/tools/dsymutil/LinkUtils.h | 7 +++++++ llvm/tools/dsymutil/Options.td | 8 ++++++++ llvm/tools/dsymutil/dsymutil.cpp | 3 +++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index b91c27e6a0f86..7f7fce49d3e71 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -794,9 +794,9 @@ bool DwarfLinkerForBinary::linkImpl( reportWarning("Could not parse binary Swift module: " + toString(FromInterfaceOrErr.takeError()), Obj->getObjectFilename()); - // Only skip swiftmodules that could be parsed and are - // positively identified as textual. - } else if (*FromInterfaceOrErr) { + // Only skip swiftmodules that could be parsed and are positively + // identified as textual. Do so only when the option allows. + } else if (*FromInterfaceOrErr && !Options.IncludeSwiftModulesFromInterface) { if (Options.Verbose) outs() << "Skipping compiled textual Swift interface: " << Obj->getObjectFilename() << "\n"; diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index ad5515a04333e..c333a3d4afee0 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -114,6 +114,13 @@ struct LinkOptions { /// Whether all remarks should be kept or only remarks with valid debug /// locations. bool RemarksKeepAll = true; + + /// Whether or not to copy binary swiftmodules built from textual + /// .swiftinterface files into the dSYM bundle. These typically come only + /// from the SDK (since textual interfaces require library evolution) and + /// thus are a waste of space to copy into the bundle. Turn this on if the + /// swiftmodules are different from those in the SDK. + bool IncludeSwiftModulesFromInterface = false; /// @} LinkOptions() = default; diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td index ad35e55e33b12..e99bc12fa7fd8 100644 --- a/llvm/tools/dsymutil/Options.td +++ b/llvm/tools/dsymutil/Options.td @@ -202,6 +202,14 @@ def remarks_drop_without_debug: Flag<["--", "-"], "remarks-drop-without-debug">, "all remarks are kept.">, Group; +def include_swiftmodules_from_interface: Flag<["--", "-"], "include-swiftmodules-from-interface">, + HelpText<"Whether or not to copy binary swiftmodules built from textual " + ".swiftinterface files into the dSYM bundle. These typically come only " + "from the SDK (since textual interfaces require library evolution) and " + "thus are a waste of space to copy into the bundle. Turn this on if the " + "swiftmodules are different from those in the SDK.">, + Group; + def linker: Separate<["--", "-"], "linker">, MetaVarName<"">, HelpText<"Specify the desired type of DWARF linker. Defaults to 'classic'">, diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 913077eb0b06d..688f6aaf3d0c9 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -391,6 +391,9 @@ static Expected getOptions(opt::InputArgList &Args) { Options.LinkOpts.RemarksKeepAll = !Args.hasArg(OPT_remarks_drop_without_debug); + Options.LinkOpts.IncludeSwiftModulesFromInterface = + Args.hasArg(OPT_include_swiftmodules_from_interface); + if (opt::Arg *BuildVariantSuffix = Args.getLastArg(OPT_build_variant_suffix)) Options.LinkOpts.BuildVariantSuffix = BuildVariantSuffix->getValue(); From 1c3fba579db64cda96c00a2bbc87b571871ac845 Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Mon, 27 Oct 2025 11:41:46 -0700 Subject: [PATCH 2/4] Add to cmdline.test --- llvm/test/tools/dsymutil/cmdline.test | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index 1574fe35f5254..0b0bce194d575 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -14,6 +14,7 @@ CHECK: -fat64 CHECK: -flat CHECK: -gen-reproducer CHECK: -help +CHECK: -include-swiftmodules-from-interface CHECK: -keep-function-for-static CHECK: -no-object-timestamp CHECK: -no-odr From 1945d6a40506342b7ea47a325f151268437673bd Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Mon, 27 Oct 2025 11:42:19 -0700 Subject: [PATCH 3/4] Fix format --- llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 7f7fce49d3e71..ee1e9060657b0 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -796,7 +796,8 @@ bool DwarfLinkerForBinary::linkImpl( Obj->getObjectFilename()); // Only skip swiftmodules that could be parsed and are positively // identified as textual. Do so only when the option allows. - } else if (*FromInterfaceOrErr && !Options.IncludeSwiftModulesFromInterface) { + } else if (*FromInterfaceOrErr && + !Options.IncludeSwiftModulesFromInterface) { if (Options.Verbose) outs() << "Skipping compiled textual Swift interface: " << Obj->getObjectFilename() << "\n"; From 26198fcaa7ef35d0fdf248ce5d771982f4433090 Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Mon, 27 Oct 2025 13:16:01 -0700 Subject: [PATCH 4/4] Fix and add tests --- llvm/docs/CommandGuide/dsymutil.rst | 8 +++++ .../swiftmodule-include-from-interface.test | 33 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 llvm/test/tools/dsymutil/ARM/swiftmodule-include-from-interface.test diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index 8e61e01d7d9c3..0e442d657e987 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -70,6 +70,14 @@ OPTIONS Print this help output. +.. option:: --include-swiftmodules-from-interface + + Whether or not to copy binary swiftmodules built from textual .swiftinterface + files into the dSYM bundle. These typically come only from the SDK (since + textual interfaces require library evolution) and thus are a waste of space to + copy into the bundle. Turn this on if the swiftmodules are different from + those in the SDK. + .. option:: --keep-function-for-static Make a static variable keep the enclosing function even if it would have been diff --git a/llvm/test/tools/dsymutil/ARM/swiftmodule-include-from-interface.test b/llvm/test/tools/dsymutil/ARM/swiftmodule-include-from-interface.test new file mode 100644 index 0000000000000..00141f12587d4 --- /dev/null +++ b/llvm/test/tools/dsymutil/ARM/swiftmodule-include-from-interface.test @@ -0,0 +1,33 @@ +# RUN: dsymutil -include-swiftmodules-from-interface -verbose -oso-prepend-path=%p -y -o %t.dSYM %s | FileCheck %s +# +# RUN: dsymutil -include-swiftmodules-from-interface --linker parallel -verbose -oso-prepend-path=%p -y %s -o %t-parallel.dSYM | FileCheck %s +# +# To regenerate: +# echo ''>I.swift +# echo ''>B.swift +# echo 'import I'>main.swift +# xcrun swiftc -emit-module-interface-path I.swiftinterface -enable-library-evolution I.swift +# xcrun swiftc -emit-module-path B.swiftmodule B.swift -Xfrontend -no-serialize-debugging-options +# xcrun swiftc -explicit-module-build main.swift -I. -module-cache-path cache -g -Xfrontend -no-serialize-debugging-options +# output is "B.swiftmodule" and "cache/I*.swiftmodule" +# +# CHECK-NOT: Skipping compiled textual Swift interface: {{.*}}/Inputs/Binary.swiftmodule +# CHECK-NOT: Skipping compiled textual Swift interface: {{.*}}/Inputs/FromInterface.swiftmodule + +# +--- +triple: 'arm64-apple-darwin' +objects: + - filename: '../Inputs/Binary.swiftmodule' + timestamp: 0 + type: 50 + symbols: [] + - filename: '../Inputs/FromInterface.swiftmodule' + timestamp: 0 + type: 50 + symbols: [] + - filename: '../Inputs/FromInterface.swiftmodule' + timestamp: 0 + type: 50 + symbols: [] +...