1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Generates a grit grd file from a list of input manifest files. This is useful
# for preventing the need to list JS files in multiple locations, as files can
# be listed just once in the BUILD.gn file as inputs for a build rule that knows
# how to output such a manifest (e.g. preprocess_if_expr).
#
# Variables:
# manifest-files:
# List of paths to manifest files. Each must contain a JSON object with
# 2 fields:
# - base_dir, the base directory where the files are located
# - files, a list of file paths from the base directory
#
# out_grd:
# Path where the generated grd file should be written.
#
# grd_prefix:
# Used to generate both grit IDs for included files and names for the
# header/pak/resource map files specified in the <outputs> section of the
# grd file. For example, prefix "foo" will result in a grd file that has
# as output "foo_resources.pak", "grit/foo_resources.h", etc, and has grit
# IDs prefixed by IDS_FOO.
#
# root_gen_dir:
# Path to the root generated directory. Used to compute the relative path
# from the root generated directory for setting file paths, as grd files
# with generated file paths must specify these paths as
# "${root_gen_dir}/<path_to_file>"
#
# input_files:
# List of file paths (from |input_files_base_dir|) that are not included in
# any manifest files, but should be added to the grd.
#
# input_files_base_dir:
# The base directory for the paths in |input_files|. |input_files| and
# |input_files_base_dir| must either both be provided or both be omitted.
import argparse
import json
import os
import sys
_CWD = os.getcwd()
GRD_BEGIN_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>\n'\
'<grit latest_public_release="0" current_release="1">\n'\
' <outputs>\n'\
' <output filename="{out_dir}/{prefix}_resources.h" '\
'type="rc_header">\n'\
' <emit emit_type=\'prepend\'></emit>\n'\
' </output>\n'\
' <output filename="{out_dir}/{prefix}_resources_map.cc"\n'\
' type="resource_file_map_source" />\n'\
' <output filename="{out_dir}/{prefix}_resources_map.h"\n'\
' type="resource_map_header" />\n'\
' <output filename="{prefix}_resources.pak" '\
'type="data_package" />\n'\
' </outputs>\n'\
' <release seq="1">\n'\
' <includes>\n'
GRD_INCLUDE_TEMPLATE = ' <include name="{name}" ' \
'file="{file}" resource_path="{path}" ' \
'use_base_dir="false" type="{type}" />\n'
GRD_END_TEMPLATE = ' </includes>\n'\
' </release>\n'\
'</grit>\n'
GRDP_BEGIN_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>\n'\
'<grit-part>\n'
GRDP_END_TEMPLATE = '</grit-part>\n'
# Generates an <include .... /> row for the given file.
def _generate_include_row(grd_prefix, filename, pathname, \
resource_path_rewrites, resource_path_prefix):
assert '\\' not in filename
assert '\\' not in pathname
name_suffix = filename.upper().replace('/', '_').replace('.', '_'). \
replace('-', '_').replace('@', '_AT_')
name = 'IDR_%s_%s' % (grd_prefix.upper(), name_suffix)
extension = os.path.splitext(filename)[1]
type = 'chrome_html' if extension == '.html' or extension == '.js' \
else 'BINDATA'
resource_path = resource_path_rewrites[filename] \
if filename in resource_path_rewrites else filename
if resource_path_prefix != None:
resource_path = resource_path_prefix + '/' + resource_path
assert '\\' not in resource_path
return GRD_INCLUDE_TEMPLATE.format(
file=pathname,
path=resource_path,
name=name,
type=type)
def _generate_part_row(filename):
return ' <part file="%s" />\n' % filename
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--manifest-files', nargs="*")
parser.add_argument('--out-grd', required=True)
parser.add_argument('--grd-prefix', required=True)
parser.add_argument('--root-gen-dir', required=True)
parser.add_argument('--input-files', nargs="*")
parser.add_argument('--input-files-base-dir')
parser.add_argument('--output-files-base-dir', default='grit')
parser.add_argument('--grdp-files', nargs="*")
parser.add_argument('--resource-path-rewrites', nargs="*")
parser.add_argument('--resource-path-prefix')
args = parser.parse_args(argv)
grd_path = os.path.normpath(os.path.join(_CWD, args.out_grd))
with open(grd_path, 'w', newline='', encoding='utf-8') as grd_file:
begin_template = GRDP_BEGIN_TEMPLATE if args.out_grd.endswith('.grdp') \
else GRD_BEGIN_TEMPLATE
grd_file.write(begin_template.format(prefix=args.grd_prefix,
out_dir=args.output_files_base_dir))
if args.grdp_files != None:
out_grd_dir = os.path.dirname(args.out_grd)
for grdp_file in args.grdp_files:
grdp_path = os.path.relpath(grdp_file, out_grd_dir).replace('\\', '/')
grd_file.write(_generate_part_row(grdp_path))
resource_path_rewrites = {}
if args.resource_path_rewrites != None:
for r in args.resource_path_rewrites:
[original, rewrite] = r.split("|")
resource_path_rewrites[original] = rewrite
if args.input_files != None:
assert(args.input_files_base_dir)
args.input_files_base_dir = args.input_files_base_dir.replace('\\', '/')
args.root_gen_dir = args.root_gen_dir.replace('\\', '/')
# Detect whether the input files reside under $root_src_dir or
# $root_gen_dir.
base_dir = os.path.join('${root_src_dir}', args.input_files_base_dir)
if args.input_files_base_dir.startswith(args.root_gen_dir + '/'):
base_dir = args.input_files_base_dir.replace(
args.root_gen_dir + '/', '${root_gen_dir}/')
for filename in args.input_files:
norm_base = os.path.normpath(args.input_files_base_dir)
norm_path = os.path.normpath(os.path.join(args.input_files_base_dir,
filename))
assert os.path.commonprefix([norm_base, norm_path]) == norm_base, \
f'Error: input_file {filename} found outside of ' + \
'input_files_base_dir'
filepath = os.path.join(base_dir, filename).replace('\\', '/')
grd_file.write(_generate_include_row(
args.grd_prefix, filename, filepath,
resource_path_rewrites, args.resource_path_prefix))
if args.manifest_files != None:
for manifest_file in args.manifest_files:
manifest_path = os.path.normpath(os.path.join(_CWD, manifest_file))
with open(manifest_path, 'r', encoding='utf-8') as f:
data = json.load(f)
base_dir= os.path.normpath(os.path.join(_CWD, data['base_dir']))
for filename in data['files']:
filepath = os.path.join(base_dir, filename)
rebased_path = os.path.relpath(filepath, args.root_gen_dir)
rebased_path = rebased_path.replace('\\', '/')
grd_file.write(_generate_include_row(
args.grd_prefix, filename, '${root_gen_dir}/' + rebased_path,
resource_path_rewrites, args.resource_path_prefix))
end_template = GRDP_END_TEMPLATE if args.out_grd.endswith('.grdp') else \
GRD_END_TEMPLATE
grd_file.write(end_template)
return
if __name__ == '__main__':
main(sys.argv[1:])
|