diff --git a/build/toolchain/gcc_ar_wrapper.py b/build/toolchain/gcc_ar_wrapper.py index de53df09e97582..a8f31903076134 100755 --- a/build/toolchain/gcc_ar_wrapper.py +++ b/build/toolchain/gcc_ar_wrapper.py @@ -16,7 +16,20 @@ import subprocess import sys -import wrapper_utils + +# When running on a Windows host and using a toolchain whose tools are +# actually wrapper scripts (i.e. .bat files on Windows) rather than binary +# executables, the "command" to run has to be prefixed with this magic. +# The GN toolchain definitions take care of that for when GN/Ninja is +# running the tool directly. When that command is passed in to this +# script, it appears as a unitary string but needs to be split up so that +# just 'cmd' is the actual command given to Python's subprocess module. +BAT_PREFIX = 'cmd /c call ' + +def CommandToRun(command): + if command[0].startswith(BAT_PREFIX): + command = command[0].split(None, 3) + command[1:] + return command def main(): @@ -31,20 +44,12 @@ def main(): metavar='ARCHIVE') parser.add_argument('--plugin', help='Load plugin') - parser.add_argument('--resource-whitelist', - help='Merge all resource whitelists into a single file.', - metavar='PATH') parser.add_argument('operation', help='Operation on the archive') parser.add_argument('inputs', nargs='+', help='Input files') args = parser.parse_args() - if args.resource_whitelist: - whitelist_candidates = wrapper_utils.ResolveRspLinks(args.inputs) - wrapper_utils.CombineResourceWhitelists( - whitelist_candidates, args.resource_whitelist) - command = [args.ar, args.operation] if args.plugin is not None: command += ['--plugin', args.plugin] @@ -59,7 +64,7 @@ def main(): raise # Now just run the ar command. - return subprocess.call(wrapper_utils.CommandToRun(command)) + return subprocess.call(CommandToRun(command)) if __name__ == "__main__": diff --git a/build/toolchain/gcc_compile_wrapper.py b/build/toolchain/gcc_compile_wrapper.py deleted file mode 100755 index 0e04dde3d3f36a..00000000000000 --- a/build/toolchain/gcc_compile_wrapper.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Runs a compilation command. - -This script exists to avoid using complex shell commands in -gcc_toolchain.gni's tool("cxx") and tool("cc") in case the host running the -compiler does not have a POSIX-like shell (e.g. Windows). -""" - -import argparse -import sys - -import wrapper_utils - - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--resource-whitelist', - help='Generate a resource whitelist for this target.', - metavar='PATH') - parser.add_argument('command', nargs=argparse.REMAINDER, - help='Compilation command') - args = parser.parse_args() - - returncode, stderr = wrapper_utils.CaptureCommandStderr( - wrapper_utils.CommandToRun(args.command)) - - used_resources = wrapper_utils.ExtractResourceIdsFromPragmaWarnings(stderr) - sys.stderr.write(stderr) - - if args.resource_whitelist: - with open(args.resource_whitelist, 'w') as f: - if used_resources: - f.write('\n'.join(str(resource) for resource in used_resources)) - f.write('\n') - - - return returncode - -if __name__ == "__main__": - sys.exit(main()) diff --git a/build/toolchain/gcc_solink_wrapper.py b/build/toolchain/gcc_solink_wrapper.py index 426f9d66332ca3..79363f91a1c103 100755 --- a/build/toolchain/gcc_solink_wrapper.py +++ b/build/toolchain/gcc_solink_wrapper.py @@ -12,17 +12,31 @@ import argparse import os +import re import subprocess import sys -import wrapper_utils + +# When running on a Windows host and using a toolchain whose tools are +# actually wrapper scripts (i.e. .bat files on Windows) rather than binary +# executables, the "command" to run has to be prefixed with this magic. +# The GN toolchain definitions take care of that for when GN/Ninja is +# running the tool directly. When that command is passed in to this +# script, it appears as a unitary string but needs to be split up so that +# just 'cmd' is the actual command given to Python's subprocess module. +BAT_PREFIX = 'cmd /c call ' + +def CommandToRun(command): + if command[0].startswith(BAT_PREFIX): + command = command[0].split(None, 3) + command[1:] + return command def CollectSONAME(args): """Replaces: readelf -d $sofile | grep SONAME""" toc = '' - readelf = subprocess.Popen(wrapper_utils.CommandToRun( - [args.readelf, '-d', args.sofile]), stdout=subprocess.PIPE, bufsize=-1) + readelf = subprocess.Popen(CommandToRun([args.readelf, '-d', args.sofile]), + stdout=subprocess.PIPE, bufsize=-1) for line in readelf.stdout: if 'SONAME' in line: toc += line @@ -32,7 +46,7 @@ def CollectSONAME(args): def CollectDynSym(args): """Replaces: nm --format=posix -g -D $sofile | cut -f1-2 -d' '""" toc = '' - nm = subprocess.Popen(wrapper_utils.CommandToRun([ + nm = subprocess.Popen(CommandToRun([ args.nm, '--format=posix', '-g', '-D', args.sofile]), stdout=subprocess.PIPE, bufsize=-1) for line in nm.stdout: @@ -82,9 +96,6 @@ def main(): required=True, help='Final output shared object file', metavar='FILE') - parser.add_argument('--resource-whitelist', - help='Merge all resource whitelists into a single file.', - metavar='PATH') parser.add_argument('command', nargs='+', help='Linking command') args = parser.parse_args() @@ -93,14 +104,8 @@ def main(): fast_env = dict(os.environ) fast_env['LC_ALL'] = 'C' - if args.resource_whitelist: - whitelist_candidates = wrapper_utils.ResolveRspLinks(args.command) - wrapper_utils.CombineResourceWhitelists( - whitelist_candidates, args.resource_whitelist) - # First, run the actual link. - result = subprocess.call( - wrapper_utils.CommandToRun(args.command), env=fast_env) + result = subprocess.call(CommandToRun(args.command), env=fast_env) if result != 0: return result @@ -115,8 +120,8 @@ def main(): # Finally, strip the linked shared object file (if desired). if args.strip: - result = subprocess.call(wrapper_utils.CommandToRun( - [args.strip, '--strip-unneeded', '-o', args.output, args.sofile])) + result = subprocess.call(CommandToRun([args.strip, '--strip-unneeded', + '-o', args.output, args.sofile])) return result diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 2ac3e48b760a92..eecb409a71c35d 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni @@ -9,7 +9,6 @@ import("//build/config/v8_target_cpu.gni") import("//build/toolchain/cc_wrapper.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") -import("//tools/grit/grit_rule.gni") # This template defines a toolchain for something that works like gcc # (including clang). @@ -221,41 +220,23 @@ template("gcc_toolchain") { object_subdir = "{{target_out_dir}}/{{label_name}}" tool("cc") { - whitelist_flag = " " - if (enable_resource_whitelist_generation) { - whitelist_flag = " --resource-whitelist=\"{{output}}.whitelist\"" - } depfile = "{{output}}.d" command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cppflags}${extra_cflags} -c {{source}} -o {{output}}" depsformat = "gcc" description = "CC {{output}}" outputs = [ - # The whitelist file is also an output, but ninja does not - # currently support multiple outputs for tool("cc"). "$object_subdir/{{source_name_part}}.o", ] - compile_wrapper = rebase_path("//build/toolchain/gcc_compile_wrapper.py", - root_build_dir) - command = "$python_path \"$compile_wrapper\"$whitelist_flag $command" } tool("cxx") { - whitelist_flag = " " - if (enable_resource_whitelist_generation) { - whitelist_flag = " --resource-whitelist=\"{{output}}.whitelist\"" - } depfile = "{{output}}.d" command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -o {{output}}" depsformat = "gcc" description = "CXX {{output}}" outputs = [ - # The whitelist file is also an output, but ninja does not - # currently support multiple outputs for tool("cxx"). "$object_subdir/{{source_name_part}}.o", ] - compile_wrapper = rebase_path("//build/toolchain/gcc_compile_wrapper.py", - root_build_dir) - command = "$python_path \"$compile_wrapper\"$whitelist_flag $command" } tool("asm") { @@ -271,17 +252,13 @@ template("gcc_toolchain") { tool("alink") { rspfile = "{{output}}.rsp" - whitelist_flag = " " - if (enable_resource_whitelist_generation) { - whitelist_flag = " --resource-whitelist=\"{{output}}.whitelist\"" - } # This needs a Python script to avoid using simple sh features in this # command, in case the host does not use a POSIX shell (e.g. compiling # POSIX-like toolchains such as NaCl on Windows). ar_wrapper = rebase_path("//build/toolchain/gcc_ar_wrapper.py", root_build_dir) - command = "$python_path \"$ar_wrapper\"$whitelist_flag --output={{output}} --ar=\"$ar\" {{arflags}} rcsD @\"$rspfile\"" + command = "$python_path \"$ar_wrapper\" --output={{output}} --ar=\"$ar\" {{arflags}} rcsD @\"$rspfile\"" description = "AR {{output}}" rspfile_content = "{{inputs}}" outputs = [ @@ -300,11 +277,6 @@ template("gcc_toolchain") { sofile = "{{output_dir}}/$soname" # Possibly including toolchain dir. rspfile = sofile + ".rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - whitelist_flag = " " - if (enable_resource_whitelist_generation) { - whitelist_file = "$sofile.whitelist" - whitelist_flag = " --resource-whitelist=\"$whitelist_file\"" - } if (defined(invoker.strip)) { unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" @@ -331,7 +303,7 @@ template("gcc_toolchain") { # requiring sh control structures, pipelines, and POSIX utilities. # The host might not have a POSIX shell and utilities (e.g. Windows). solink_wrapper = rebase_path("//build/toolchain/gcc_solink_wrapper.py") - command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch --sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\" --output=\"$sofile\"$whitelist_flag -- $link_command" + command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch --sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\" --output=\"$sofile\" -- $link_command" rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" @@ -360,9 +332,6 @@ template("gcc_toolchain") { sofile, tocfile, ] - if (enable_resource_whitelist_generation) { - outputs += [ whitelist_file ] - } if (sofile != unstripped_sofile) { outputs += [ unstripped_sofile ] } diff --git a/build/toolchain/wrapper_utils.py b/build/toolchain/wrapper_utils.py deleted file mode 100644 index 163a292c165cc0..00000000000000 --- a/build/toolchain/wrapper_utils.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Helper functions for gcc_toolchain.gni wrappers.""" - -import os -import re -import subprocess -import shlex -import sys - -_BAT_PREFIX = 'cmd /c call ' -_WHITELIST_RE = re.compile('whitelisted_resource_(?P[0-9]+)') - - -def CommandToRun(command): - """Generates commands compatible with Windows. - - When running on a Windows host and using a toolchain whose tools are - actually wrapper scripts (i.e. .bat files on Windows) rather than binary - executables, the |command| to run has to be prefixed with this magic. - The GN toolchain definitions take care of that for when GN/Ninja is - running the tool directly. When that command is passed in to this - script, it appears as a unitary string but needs to be split up so that - just 'cmd' is the actual command given to Python's subprocess module. - - Args: - command: List containing the UNIX style |command|. - - Returns: - A list containing the Windows version of the |command|. - """ - if command[0].startswith(_BAT_PREFIX): - command = command[0].split(None, 3) + command[1:] - return command - - -def ResolveRspLinks(inputs): - """Return a list of files contained in a response file. - - Args: - inputs: A command containing rsp files. - - Returns: - A set containing the rsp file content.""" - rspfiles = [a[1:] for a in inputs if a.startswith('@')] - resolved = set() - for rspfile in rspfiles: - with open(rspfile, 'r') as f: - resolved.update(shlex.split(f.read())) - - return resolved - - -def CombineResourceWhitelists(whitelist_candidates, outfile): - """Combines all whitelists for a resource file into a single whitelist. - - Args: - whitelist_candidates: List of paths to rsp files containing all targets. - outfile: Path to save the combined whitelist. - """ - whitelists = ('%s.whitelist' % candidate for candidate in whitelist_candidates - if os.path.exists('%s.whitelist' % candidate)) - - resources = set() - for whitelist in whitelists: - with open(whitelist, 'r') as f: - resources.update(f.readlines()) - - with open(outfile, 'w') as f: - f.writelines(resources) - - -def ExtractResourceIdsFromPragmaWarnings(text): - """Returns set of resource IDs that are inside unknown pragma warnings. - - Args: - text: The text that will be scanned for unknown pragma warnings. - - Returns: - A set containing integers representing resource IDs. - """ - used_resources = set() - lines = text.splitlines() - for ln in lines: - match = _WHITELIST_RE.search(ln) - if match: - resource_id = int(match.group('resource_id')) - used_resources.add(resource_id) - - return used_resources - - -def CaptureCommandStderr(command): - """Returns the stderr of a command. - - Args: - args: A list containing the command and arguments. - cwd: The working directory from where the command should be made. - env: Environment variables for the new process. - """ - child = subprocess.Popen(command, stderr=subprocess.PIPE) - _, stderr = child.communicate() - return child.returncode, stderr diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 8d3fe4853147f4..dbe6e7c1783ef2 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn @@ -17,10 +17,6 @@ import("//chrome/version.gni") import("//ui/base/ui_features.gni") import("//v8/gni/v8.gni") -if (enable_resource_whitelist_generation) { - android_resource_whitelist = "$root_gen_dir/chrome/resource_whitelist.txt" -} - if (is_android) { import("//build/config/android/rules.gni") } else if (is_mac) { @@ -1459,11 +1455,6 @@ repack("packed_extra_resources") { } else { output = "$root_out_dir/resources.pak" } - - if (enable_resource_whitelist_generation) { - repack_whitelist = android_resource_whitelist - deps += [ "//chrome:resource_whitelist" ] - } } # GYP version: chrome/chrome_resources.gyp:browser_tests_pak @@ -1578,11 +1569,6 @@ template("chrome_repack_percent") { } output = repack_output_file - - if (enable_resource_whitelist_generation) { - repack_whitelist = android_resource_whitelist - deps += [ "//chrome:resource_whitelist" ] - } } copy(copy_name) { @@ -1696,33 +1682,6 @@ if (is_android) { } } -if (enable_resource_whitelist_generation) { - action("resource_whitelist") { - deps = [ - "//chrome/android:chrome", - ] - script = "//tools/resources/generate_resource_whitelist.py" - - _infile = "$root_out_dir/libchrome.cr.so.whitelist" - inputs = [ - _infile, - ] - - _outfile = android_resource_whitelist - outputs = [ - _outfile, - ] - - args = [ - "-i", - rebase_path(_infile, root_build_dir), - "-o", - rebase_path(_outfile, root_build_dir), - "--out-dir=.", - ] - } -} - if (is_linux) { action("manpage") { if (is_chrome_branded) { diff --git a/chrome/chrome_repack_locales.gni b/chrome/chrome_repack_locales.gni index b9a1d95f17bde2..83b1e19a33b505 100644 --- a/chrome/chrome_repack_locales.gni +++ b/chrome/chrome_repack_locales.gni @@ -6,7 +6,6 @@ import("//build/config/chrome_build.gni") import("//build/config/features.gni") import("//build/config/ui.gni") import("//tools/grit/repack.gni") -import("//tools/grit/grit_rule.gni") # Arguments: # @@ -119,10 +118,6 @@ template("_repack_one_locale") { ] } - if (enable_resource_whitelist_generation) { - repack_whitelist = "$root_gen_dir/chrome/resource_whitelist.txt" - deps += [ "//chrome:resource_whitelist" ] - } output = invoker.output } } diff --git a/tools/grit/grit/format/data_pack.py b/tools/grit/grit/format/data_pack.py index 9f92b7c608b791..02616c39d40443 100755 --- a/tools/grit/grit/format/data_pack.py +++ b/tools/grit/grit/format/data_pack.py @@ -109,8 +109,7 @@ def WriteDataPack(resources, output_file, encoding): file.write(content) -def RePack(output_file, input_files, whitelist_file=None, - suppress_removed_key_output=False): +def RePack(output_file, input_files, whitelist_file=None): """Write a new data pack file by combining input pack files. Args: @@ -119,8 +118,6 @@ def RePack(output_file, input_files, whitelist_file=None, whitelist_file: path to the file that contains the list of resource IDs that should be kept in the output file or None to include all resources. - suppress_removed_key_output: allows the caller to suppress the output from - RePackFromDataPackStrings. Raises: KeyError: if there are duplicate keys or resource encoding is @@ -131,20 +128,17 @@ def RePack(output_file, input_files, whitelist_file=None, if whitelist_file: whitelist = util.ReadFile(whitelist_file, util.RAW_TEXT).strip().split('\n') whitelist = set(map(int, whitelist)) - resources, encoding = RePackFromDataPackStrings( - input_data_packs, whitelist, suppress_removed_key_output) + resources, encoding = RePackFromDataPackStrings(input_data_packs, whitelist) WriteDataPack(resources, output_file, encoding) -def RePackFromDataPackStrings(inputs, whitelist, - suppress_removed_key_output=False): +def RePackFromDataPackStrings(inputs, whitelist): """Returns a data pack string that combines the resources from inputs. Args: inputs: a list of data pack strings that need to be combined. whitelist: a list of resource IDs that should be kept in the output string or None to include all resources. - suppress_removed_key_output: Do not print removed keys. Returns: DataPackContents: a tuple containing the new combined data pack and its @@ -176,9 +170,8 @@ def RePackFromDataPackStrings(inputs, whitelist, resources.update(whitelisted_resources) removed_keys = [key for key in content.resources.keys() if key not in whitelist] - if not suppress_removed_key_output: - for key in removed_keys: - print 'RePackFromDataPackStrings Removed Key:', key + for key in removed_keys: + print 'RePackFromDataPackStrings Removed Key:', key else: resources.update(content.resources) diff --git a/tools/grit/grit/format/repack.py b/tools/grit/grit/format/repack.py index fa0088c5ddfb8e..c4a593a82d2c06 100755 --- a/tools/grit/grit/format/repack.py +++ b/tools/grit/grit/format/repack.py @@ -27,16 +27,13 @@ def main(argv): parser.add_option('--whitelist', action='store', dest='whitelist', default=None, help='Full path to the whitelist used to' 'filter output pak file resource IDs') - parser.add_option('--suppress-removed-key-output', action='store_true') options, file_paths = parser.parse_args(argv) if len(file_paths) < 2: parser.error('Please specify output and at least one input filenames') - grit.format.data_pack.RePack( - file_paths[0], file_paths[1:], - whitelist_file=options.whitelist, - suppress_removed_key_output=options.suppress_removed_key_output) + grit.format.data_pack.RePack(file_paths[0], file_paths[1:], + whitelist_file=options.whitelist) if '__main__' == __name__: main(sys.argv[1:]) diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni index d1207ad63e5f0e..d314e9b82a60b0 100644 --- a/tools/grit/grit_rule.gni +++ b/tools/grit/grit_rule.gni @@ -85,14 +85,10 @@ import("//build/config/ui.gni") import("//third_party/closure_compiler/closure_args.gni") declare_args() { - # Enables used resource whitelist generation. Set for official builds only - # as a large amount of build output is generated. - enable_resource_whitelist_generation = is_android && is_official_build + # Enables used resource whitelist generation. + enable_resource_whitelist_generation = false } -assert(!enable_resource_whitelist_generation || is_android, - "resource whitelist generation only works on android") - grit_defines = [] # Mac and iOS want Title Case strings. diff --git a/tools/grit/repack.gni b/tools/grit/repack.gni index 0f257bb7c4274c..7dd1520a56263f 100644 --- a/tools/grit/repack.gni +++ b/tools/grit/repack.gni @@ -2,7 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tools/grit/grit_rule.gni") +declare_args() { + # Absolute path to a resource whitelist (generated using + # //tools/resources/find_used_resources.py). + repack_whitelist = "" +} # This file defines a template to invoke grit repack in a consistent manner. # @@ -37,11 +41,11 @@ template("repack") { ] args = [] - if (defined(invoker.repack_whitelist)) { - inputs += [ invoker.repack_whitelist ] - _rebased_whitelist = rebase_path(invoker.repack_whitelist) - args += [ "--whitelist=$_rebased_whitelist" ] - args += [ "--suppress-removed-key-output" ] + if (repack_whitelist != "") { + assert( + repack_whitelist == rebase_path(repack_whitelist), + "repack_whitelist must be an absolute path. Current value is $repack_whitelist") + args += [ "--whitelist=$repack_whitelist" ] } args += [ rebase_path(invoker.output, root_build_dir) ] args += rebase_path(invoker.sources, root_build_dir) diff --git a/tools/resources/generate_resource_whitelist.py b/tools/resources/find_used_resources.py similarity index 59% rename from tools/resources/generate_resource_whitelist.py rename to tools/resources/find_used_resources.py index 527ceb484158c9..0528115ead59cf 100755 --- a/tools/resources/generate_resource_whitelist.py +++ b/tools/resources/find_used_resources.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright 2016 The Chromium Authors. All rights reserved. +# Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -8,22 +8,18 @@ import re import sys -USAGE = """generate_resource_whitelist.py [-h] [-i INPUT] [-o OUTPUT] +USAGE = """find_used_resources.py [-h] [-i INPUT] [-o OUTPUT] -INPUT specifies a file containing existing resource IDs that should be -whitelisted, where each line of INPUT contains a single resource ID. - -Creates a resource whitelist by collecting existing resource IDs that are part -of unknown pragma warnings and adds additional arch specfic resource IDs. +Outputs the sorted list of resource ids that are part of unknown pragma warning +in the given build log. This script is used to find the resources that are actually compiled in Chrome -in order to only include the needed strings/images in Chrome PAK files. -These resource IDs show up in the build output after building Chrome with -gn variable enable_resource_whitelist_generation set to true. -This causes the compiler to print out an UnknownPragma message every time a -resource ID is used. - -E.g. foo.cc:22:0: warning: ignoring #pragma whitelisted_resource_12345 +in order to only include the needed strings/images in Chrome PAK files. The +script parses out the list of used resource ids. These resource ids show up in +the build output after building Chrome with gyp variable +enable_resource_whitelist_generation set to 1. This gyp flag causes the compiler +to print out a UnknownPragma message every time a resource id is used. E.g.: +foo.cc:22:0: warning: ignoring #pragma whitelisted_resource_12345 [-Wunknown-pragmas] On Windows, the message is simply a message via __pragma(message(...)). @@ -39,8 +35,7 @@ 'IDS_VERSION_UI_32BIT', ] - -def _FindResourceIds(header, resource_names): +def FindResourceIds(header, resource_names): """Returns the numerical resource IDs that correspond to the given resource names, as #defined in the given header file." """ @@ -54,24 +49,36 @@ def _FindResourceIds(header, resource_names): ', '.join(str(i) for i in res_ids)) return set(res_ids) - -def main(): +def GetResourceIdsInPragmaWarnings(input): + """Returns set of resource ids that are inside unknown pragma warnings + for the given input. + """ + used_resources = set() + unknown_pragma_warning_pattern = re.compile( + 'whitelisted_resource_(?P[0-9]+)') + for ln in input: + match = unknown_pragma_warning_pattern.search(ln) + if match: + resource_id = int(match.group('resource_id')) + used_resources.add(resource_id) + return used_resources + +def Main(): parser = argparse.ArgumentParser(usage=USAGE) parser.add_argument( '-i', '--input', type=argparse.FileType('r'), default=sys.stdin, - help='A resource whitelist where each line contains one resource ID') + help='The build log to read (default stdin)') parser.add_argument( '-o', '--output', type=argparse.FileType('w'), default=sys.stdout, help='The resource list path to write (default stdout)') - parser.add_argument( - '--out-dir', required=True, + parser.add_argument('--out-dir', required=True, help='The out target directory, for example out/Release') args = parser.parse_args() - used_resources = set() - used_resources.update([int(resource_id) for resource_id in args.input]) - used_resources |= _FindResourceIds( + + used_resources = GetResourceIdsInPragmaWarnings(args.input) + used_resources |= FindResourceIds( os.path.join(args.out_dir, COMPONENTS_STRINGS_HEADER), ARCH_SPECIFIC_RESOURCES) @@ -79,4 +86,4 @@ def main(): args.output.write('%d\n' % resource_id) if __name__ == '__main__': - main() + Main()