build: make orderfile generation public
This CL allows orderfiles to be generated and tested without an internal
checkout of chromium. To do this, pass --public when calling
tools/cygprofile/orderfile_generator_backend.py.
The orderfiles will be placed in //orderfiles.
You can set 'chrome_orderfile = "//orderfiles/orderfile.$ARCH.out"'
to use the orderfile when building.
Bug: 922460
Change-Id: I349834e80ce34766f0ba9c9e0b4db91c34323274
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524297
Reviewed-by: Matthew Cary <mattcary@chromium.org>
Commit-Queue: Matthew Cary <mattcary@chromium.org>
Cr-Commit-Position: refs/heads/master@{#643779}
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py
index 471b9e9..be93a1c 100755
--- a/tools/cygprofile/orderfile_generator_backend.py
+++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -241,7 +241,8 @@
"""Handles compilation of clank."""
def __init__(self, out_dir, step_recorder, arch, jobs, max_load, use_goma,
- goma_dir, system_health_profiling, monochrome):
+ goma_dir, system_health_profiling, monochrome, public,
+ orderfile_location):
self._out_dir = out_dir
self._step_recorder = step_recorder
self._arch = arch
@@ -250,6 +251,8 @@
self._use_goma = use_goma
self._goma_dir = goma_dir
self._system_health_profiling = system_health_profiling
+ self._public = public
+ self._orderfile_location = orderfile_location
if monochrome:
self._apk = 'Monochrome.apk'
self._apk_target = 'monochrome_apk'
@@ -260,6 +263,9 @@
self._apk_target = 'chrome_apk'
self._libname = 'libchrome'
self._libchrome_target = 'libchrome'
+ if public:
+ self._apk = self._apk.replace('.apk', 'Public.apk')
+ self._apk_target = self._apk_target.replace('_apk', '_public_apk')
self.obj_dir = os.path.join(self._out_dir, 'Release', 'obj')
self.lib_chrome_so = os.path.join(
@@ -279,7 +285,7 @@
# Set the "Release Official" flavor, the parts affecting performance.
args = [
'enable_resource_whitelist_generation=false',
- 'is_chrome_branded=true',
+ 'is_chrome_branded=' + str(not self._public).lower(),
'is_debug=false',
'is_official_build=true',
'target_os="android"',
@@ -293,6 +299,12 @@
args += ['devtools_instrumentation_dumping = ' +
str(instrumented).lower()]
+ if self._public and os.path.exists(self._orderfile_location):
+ # GN needs the orderfile path to be source-absolute.
+ src_abs_orderfile = os.path.relpath(self._orderfile_location,
+ constants.DIR_SOURCE_ROOT)
+ args += ['chrome_orderfile="//{}"'.format(src_abs_orderfile)]
+
self._step_recorder.RunCommand(
['gn', 'gen', os.path.join(self._out_dir, 'Release'),
'--args=' + ' '.join(args)])
@@ -461,34 +473,55 @@
raise NotImplementedError
+class OrderfileNoopUpdater(OrderfileUpdater):
+ def CommitFileHashes(self, unpatched_orderfile_filename, orderfile_filename):
+ # pylint: disable=unused-argument
+ return
+
+ def UploadToCloudStorage(self, filename, use_debug_location):
+ # pylint: disable=unused-argument
+ return
+
+ def _CommitFiles(self, files_to_commit, commit_message_lines):
+ raise NotImplementedError
+
+
class OrderfileGenerator(object):
"""A utility for generating a new orderfile for Clank.
Builds an instrumented binary, profiles a run of the application, and
generates an updated orderfile.
"""
- _CLANK_REPO = os.path.join(constants.DIR_SOURCE_ROOT, 'clank')
_CHECK_ORDERFILE_SCRIPT = os.path.join(
constants.DIR_SOURCE_ROOT, 'tools', 'cygprofile', 'check_orderfile.py')
_BUILD_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(
constants.GetOutDirectory()))) # Normally /path/to/src
- _UNPATCHED_ORDERFILE_FILENAME = os.path.join(
- _CLANK_REPO, 'orderfiles', 'unpatched_orderfile.%s')
-
- _PATH_TO_ORDERFILE = os.path.join(_CLANK_REPO, 'orderfiles',
- 'orderfile.%s.out')
-
# Previous orderfile_generator debug files would be overwritten.
_DIRECTORY_FOR_DEBUG_FILES = '/tmp/orderfile_generator_debug_files'
+ def _PrepareOrderfilePaths(self):
+ if self._options.public:
+ self._clank_dir = os.path.join(constants.DIR_SOURCE_ROOT,
+ '')
+ if not os.path.exists(os.path.join(self._clank_dir, 'orderfiles')):
+ os.makedirs(os.path.join(self._clank_dir, 'orderfiles'))
+ else:
+ self._clank_dir = os.path.join(constants.DIR_SOURCE_ROOT,
+ 'clank')
+
+ self._unpatched_orderfile_filename = os.path.join(
+ self._clank_dir, 'orderfiles', 'unpatched_orderfile.%s')
+ self._path_to_orderfile = os.path.join(
+ self._clank_dir, 'orderfiles', 'orderfile.%s.out')
+
def _GetPathToOrderfile(self):
"""Gets the path to the architecture-specific orderfile."""
- return self._PATH_TO_ORDERFILE % self._options.arch
+ return self._path_to_orderfile % self._options.arch
def _GetUnpatchedOrderfileFilename(self):
"""Gets the path to the architecture-specific unpatched orderfile."""
- return self._UNPATCHED_ORDERFILE_FILENAME % self._options.arch
+ return self._unpatched_orderfile_filename % self._options.arch
def _SetDevice(self):
""" Selects the device to be used by the script.
@@ -540,6 +573,8 @@
self._uninstrumented_out_dir = os.path.join(
self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')
+ self._PrepareOrderfilePaths()
+
if options.profile:
output_directory = os.path.join(self._instrumented_out_dir, 'Release')
host_profile_dir = os.path.join(output_directory, 'profile_data')
@@ -569,8 +604,13 @@
self._output_data = {}
self._step_recorder = StepRecorder(options.buildbot)
self._compiler = None
+ if orderfile_updater_class is None:
+ if options.public:
+ orderfile_updater_class = OrderfileNoopUpdater
+ else:
+ orderfile_updater_class = OrderfileUpdater
assert issubclass(orderfile_updater_class, OrderfileUpdater)
- self._orderfile_updater = orderfile_updater_class(self._CLANK_REPO,
+ self._orderfile_updater = orderfile_updater_class(self._clank_dir,
self._step_recorder,
options.branch,
options.netrc)
@@ -767,23 +807,6 @@
self._orderfile_updater.UploadToCloudStorage(
file_name, use_debug_location=False)
- def _GetHashFilePathAndContents(self, base_file):
- """Gets the name and content of the hash file created from uploading the
- given file.
-
- Args:
- base_file: The file that was uploaded to cloud storage.
-
- Returns:
- A tuple of the hash file name, relative to the clank repo path, and the
- content, which should be the sha1 hash of the file
- ('base_file.sha1', hash)
- """
- abs_file_name = base_file + '.sha1'
- rel_file_name = os.path.relpath(abs_file_name, self._CLANK_REPO)
- with open(abs_file_name, 'r') as f:
- return (rel_file_name, f.read())
-
def Generate(self):
"""Generates and maybe upload an order."""
profile_uploaded = False
@@ -807,7 +830,8 @@
self._step_recorder, self._options.arch, self._options.jobs,
self._options.max_load, self._options.use_goma,
self._options.goma_dir, self._options.system_health_orderfile,
- self._monochrome)
+ self._monochrome, self._options.public,
+ self._GetPathToOrderfile())
if not self._options.pregenerated_profiles:
# If there are pregenerated profiles, the instrumented build should
# not be changed to avoid invalidating the pregenerated profile
@@ -844,7 +868,9 @@
self._uninstrumented_out_dir, self._step_recorder,
self._options.arch, self._options.jobs, self._options.max_load,
self._options.use_goma, self._options.goma_dir,
- self._options.system_health_orderfile, self._monochrome)
+ self._options.system_health_orderfile, self._monochrome,
+ self._options.public, self._GetPathToOrderfile())
+
self._compiler.CompileLibchrome(False)
self._PatchOrderfile()
# Because identical code folding is a bit different with and without
@@ -938,6 +964,9 @@
'--use-goma', action='store_true', help='Enable GOMA.', default=False)
parser.add_argument('--adb-path', help='Path to the adb binary.')
+ parser.add_argument('--public', action='store_true',
+ help='Required if your checkout is non-internal.',
+ default=False)
parser.add_argument('--nosystem-health-orderfile', action='store_false',
dest='system_health_orderfile', default=True,
help=('Create an orderfile based on an about:blank '
@@ -988,12 +1017,15 @@
return parser
-def CreateOrderfile(options, orderfile_updater_class):
+def CreateOrderfile(options, orderfile_updater_class=None):
"""Creates an oderfile.
Args:
options: As returned from optparse.OptionParser.parse_args()
orderfile_updater_class: (OrderfileUpdater) subclass of OrderfileUpdater.
+ Use to explicitly set an OrderfileUpdater class,
+ the defaults are OrderfileUpdater, or
+ OrderfileNoopUpdater if --public is set.
Returns:
True iff success.
@@ -1026,7 +1058,7 @@
def main():
parser = CreateArgumentParser()
options = parser.parse_args()
- return 0 if CreateOrderfile(options, OrderfileUpdater) else 1
+ return 0 if CreateOrderfile(options) else 1
if __name__ == '__main__':