Process dSYMs from aspect instead of envvar.
Allows us to process dSYM bundles without having to rely on a project
-scoped user defined environment variable.
PiperOrigin-RevId: 188918053
diff --git a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
index b42a119..4626de8 100644
--- a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
+++ b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
@@ -913,11 +913,17 @@
tulsi_generated_files += depset(
[x for x in all_files.to_list() if not x.is_source])
+ has_dsym = False
+ if hasattr(ctx.fragments, 'objc'):
+ if apple_common.AppleDebugOutputs in target:
+ has_dsym = ctx.fragments.objc.generate_dsym
+
info = _struct_omitting_none(
artifacts=artifacts,
generated_sources=[(x.path, x.short_path) for x in tulsi_generated_files],
bundle_name=bundle_name,
- embedded_bundles=embedded_bundles.to_list())
+ embedded_bundles=embedded_bundles.to_list(),
+ has_dsym=has_dsym)
output = ctx.new_file(target.label.name + '.tulsiouts')
ctx.file_action(output, info.to_json())
@@ -927,7 +933,7 @@
'tulsi-outputs': [output],
},
tulsi_generated_files=tulsi_generated_files,
- transitive_embedded_bundles=embedded_bundles,
+ transitive_embedded_bundles=embedded_bundles
)
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index a6c8a5d..2b07837 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -1547,7 +1547,7 @@
}
let shellScript = "set -e\n" +
"\(changeDirectoryAction)\n" +
- "exec \(commandLine) --install_generated_artifacts"
+ "exec \(commandLine)"
let buildPhase = PBXShellScriptBuildPhase(shellScript: shellScript, shellPath: "/bin/bash")
buildPhase.showEnvVarsInLog = true
diff --git a/src/TulsiGenerator/Scripts/bazel_build.py b/src/TulsiGenerator/Scripts/bazel_build.py
index 35d7cdd..a0760af 100755
--- a/src/TulsiGenerator/Scripts/bazel_build.py
+++ b/src/TulsiGenerator/Scripts/bazel_build.py
@@ -247,7 +247,6 @@
'--config=%s_%s' % (config_platform, arch))
self.verbose = 0
- self.install_generated_artifacts = False
self.bazel_bin_path = 'bazel-bin'
self.bazel_executable = None
@@ -358,10 +357,7 @@
arg = args[0]
args = args[1:]
- if arg == '--install_generated_artifacts':
- self.install_generated_artifacts = True
-
- elif arg.startswith('--bazel_startup_options'):
+ if arg.startswith('--bazel_startup_options'):
config = self._ParseConfigFilter(arg)
args, items, terminated = self._ParseDoubleDashDelimitedItems(args)
if not terminated:
@@ -680,59 +676,60 @@
if exit_code:
return exit_code
- if parser.install_generated_artifacts:
- timer = Timer('Installing artifacts', 'installing_artifacts').Start()
- exit_code = self._InstallArtifact(outputs)
- timer.End()
+ exit_code, outputs_data = self._ExtractAspectOutputsData(outputs)
+ if exit_code:
+ return exit_code
+
+ timer = Timer('Installing artifacts', 'installing_artifacts').Start()
+ exit_code = self._InstallArtifact(outputs_data)
+ timer.End()
+ if exit_code:
+ return exit_code
+
+ timer = Timer('Installing generated headers',
+ 'installing_generated_headers').Start()
+ exit_code = self._InstallGeneratedHeaders(outputs_data)
+ timer.End()
+ if exit_code:
+ return exit_code
+
+ exit_code, dsym_paths = self._InstallDSYMBundles(
+ self.built_products_dir, outputs_data)
+ if exit_code:
+ return exit_code
+
+ if dsym_paths:
+ for path in dsym_paths:
+ # Starting with Xcode 9.x, a plist based solution exists for dSYM
+ # bundles that works with Swift as well as (Obj-)C(++).
+ if self.xcode_version_major >= 900:
+ timer = Timer('Adding remappings as plists to dSYM',
+ 'plist_dsym').Start()
+ exit_code = self._PlistdSYMPaths(path)
+ timer.End()
+ if exit_code:
+ _PrintXcodeError('Remapping dSYMs process returned %i, please '
+ 'report a Tulsi bug and attach a full Xcode '
+ 'build log.' % exit_code)
+ return exit_code
+ else:
+ timer = Timer('Patching DSYM source file paths',
+ 'patching_dsym').Start()
+ exit_code = self._PatchdSYMPaths(path)
+ timer.End()
+ if exit_code:
+ return exit_code
+
+ # Starting with Xcode 7.3, XCTests inject several supporting frameworks
+ # into the test host that need to be signed with the same identity as
+ # the host itself.
+ if (self.is_test and self.xcode_version_minor >= 730 and
+ not self.platform_name.startswith('macos') and
+ self.codesigning_allowed):
+ exit_code = self._ResignTestArtifacts()
if exit_code:
return exit_code
- timer = Timer('Installing generated headers',
- 'installing_generated_headers').Start()
- exit_code = self._InstallGeneratedHeaders(outputs)
- timer.End()
- if exit_code:
- return exit_code
-
- if self.generate_dsym:
- timer = Timer('Installing DSYM bundles', 'installing_dsym').Start()
- exit_code, dsym_paths = self._InstallDSYMBundles(
- self.built_products_dir, outputs)
- timer.End()
- if exit_code:
- return exit_code
-
- for path in dsym_paths:
- # Starting with Xcode 9.x, a plist based solution exists for dSYM
- # bundles that works with Swift as well as (Obj-)C(++).
- if self.xcode_version_major >= 900:
- timer = Timer('Adding remappings as plists to dSYM',
- 'plist_dsym').Start()
- exit_code = self._PlistdSYMPaths(path)
- timer.End()
- if exit_code:
- _PrintXcodeError('Remapping dSYMs process returned %i, please '
- 'report a Tulsi bug and attach a full Xcode '
- 'build log.' % exit_code)
- return exit_code
- else:
- timer = Timer('Patching DSYM source file paths',
- 'patching_dsym').Start()
- exit_code = self._PatchdSYMPaths(path)
- timer.End()
- if exit_code:
- return exit_code
-
- # Starting with Xcode 7.3, XCTests inject several supporting frameworks
- # into the test host that need to be signed with the same identity as
- # the host itself.
- if (self.is_test and self.xcode_version_minor >= 730 and
- not self.platform_name.startswith('macos') and
- self.codesigning_allowed):
- exit_code = self._ResignTestArtifacts()
- if exit_code:
- return exit_code
-
# Starting with Xcode 8, .lldbinit files are honored during Xcode debugging
# sessions. This allows use of the target.source-map field to remap the
# debug symbol paths encoded in the binary to the paths expected by Xcode.
@@ -742,14 +739,14 @@
# correction applies to debug prefix maps as well.
if self.xcode_version_major >= 800:
timer = Timer('Updating .lldbinit', 'updating_lldbinit').Start()
- clear_source_map = self.generate_dsym or self.use_debug_prefix_map
+ clear_source_map = dsym_paths or self.use_debug_prefix_map
exit_code = self._UpdateLLDBInit(clear_source_map)
timer.End()
if exit_code:
_PrintXcodeWarning('Updating .lldbinit action failed with code %d' %
exit_code)
- if self.generate_dsym:
+ if dsym_paths:
# TODO(b/71705491): Find a means where LLDB and associated tooling can
# locate the dSYM bundle, accounting for Spotlight latency.
#
@@ -908,7 +905,34 @@
return 1, output_locations
return process.returncode, output_locations
- def _InstallArtifact(self, outputs):
+ def _ExtractAspectOutputsData(self, output_files):
+ """Converts aspect output from paths to json to a list of dictionaries.
+
+ Args:
+ output_files: A list of strings to files representing Bazel aspect output
+ in UTF-8 JSON format.
+
+ Returns:
+ return_code, [dict]: A tuple with a return code as its first argument and
+ for its second argument, a list of dictionaries for
+ each output_file that could be interpreted as valid
+ JSON, representing the returned Bazel aspect
+ information.
+ return_code, None: If an error occurred while converting the list of
+ files into JSON.
+ """
+ outputs_data = []
+ for output_file in output_files:
+ try:
+ output_data = json.load(open(output_file))
+ except (ValueError, IOError) as e:
+ _PrintXcodeError('Failed to load output map ""%s". '
+ '%s' % (output_file, e))
+ return 600, None
+ outputs_data.append(output_data)
+ return 0, outputs_data
+
+ def _InstallArtifact(self, outputs_data):
"""Installs Bazel-generated artifacts into the Xcode output directory."""
xcode_artifact_path = self.artifact_output_path
@@ -927,20 +951,19 @@
'%s' % (xcode_artifact_path, e))
return 600
- try:
- output_data = json.load(open(outputs[0]))
- except (ValueError, IOError) as e:
- _PrintXcodeError('Failed to load output map ""%s". '
- '%s' % (outputs[0], e))
+ if not outputs_data:
+ _PrintXcodeError('Failed to load top level output file.')
return 600
- if 'artifacts' not in output_data:
+ primary_output_data = outputs_data[0]
+
+ if 'artifacts' not in primary_output_data:
_PrintXcodeError(
'Failed to find an output artifact for target %s in output map %r' %
- (xcode_artifact_path, output_data))
+ (xcode_artifact_path, primary_output_data))
return 601
- primary_artifact = output_data['artifacts'][0]
+ primary_artifact = primary_output_data['artifacts'][0]
# The PRODUCT_NAME used by the Xcode project is not trustable as it may be
# modified by the user and, more importantly, may have been modified by
@@ -952,7 +975,7 @@
os.path.basename(primary_artifact))[0]
if primary_artifact.endswith('.ipa') or primary_artifact.endswith('.zip'):
- bundle_name = output_data.get('bundle_name')
+ bundle_name = primary_output_data.get('bundle_name')
exit_code = self._UnpackTarget(primary_artifact,
xcode_artifact_path,
bundle_name)
@@ -971,7 +994,7 @@
xcode_artifact_path)
# No return code check as this is not an essential operation.
- self._InstallEmbeddedBundlesIfNecessary(output_data)
+ self._InstallEmbeddedBundlesIfNecessary(primary_output_data)
return 0
@@ -1002,7 +1025,7 @@
timer.End()
- def _InstallGeneratedHeaders(self, output_files):
+ def _InstallGeneratedHeaders(self, outputs_data):
"""Installs Bazel-generated headers into _tulsi-includes directory."""
# The folder must begin with an underscore as otherwise Bazel will delete
@@ -1014,8 +1037,7 @@
else:
os.mkdir(tulsi_root)
- for f in output_files:
- data = json.load(open(f))
+ for data in outputs_data:
if 'generated_sources' not in data:
continue
@@ -1174,25 +1196,28 @@
return 0
- def _InstallDSYMBundles(self, output_dir, aspect_outputs):
+ def _InstallDSYMBundles(self, output_dir, outputs_data):
"""Copies any generated dSYM bundles to the given directory."""
- target_dsym = os.environ.get('DWARF_DSYM_FILE_NAME')
- if not target_dsym: # If Xcode is not expecting a dSYM output, skip.
+ # Indicates that our aspect reports a dSYM was generated for this build.
+ has_dsym = outputs_data[0]['has_dsym']
+
+ if not has_dsym:
return 0, None
- dsym_to_process = set([(self.build_path, target_dsym)])
+ # Start the timer now that we know we have dSYM bundles to install.
+ timer = Timer('Installing DSYM bundles', 'installing_dsym').Start()
+
+ # Declares the Xcode-generated name of our main target's dSYM.
+ # This environment variable is always set, for any possible Xcode output
+ # that could generate a dSYM bundle.
+ target_dsym = os.environ.get('DWARF_DSYM_FILE_NAME')
+ if target_dsym:
+ dsym_to_process = set([(self.build_path, target_dsym)])
# Collect additional dSYM bundles generated by the dependencies of this
# build such as extensions or frameworks.
child_dsyms = set()
- for path in aspect_outputs:
- try:
- data = json.load(open(path))
- except (ValueError, IOError) as e:
- _PrintXcodeWarning('Failed to load output map ""%s".'
- '%s' % (path, e))
- break
-
+ for data in outputs_data:
for bundle_info in data.get('embedded_bundles', []):
if not bundle_info['has_dsym']:
continue
@@ -1219,6 +1244,7 @@
else:
dsyms_found.append(path)
+ timer.End()
return 0, dsyms_found
def _ResignBundle(self, bundle_path, signing_identity, entitlements=None):