You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
6.6 KiB
213 lines
6.6 KiB
#!/usr/bin/python3
|
|
|
|
# Copyright (C) 2018 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Updates libchrome.
|
|
|
|
This script uprevs the libchrome library with newer Chromium code.
|
|
How to use:
|
|
|
|
Prepare your local Chromium repository with the target revision.
|
|
$ cd external/libchrome
|
|
$ python3 libchrome_tools/update_libchrome.py \
|
|
--chromium_root=${PATH_TO_YOUR_LOCAL_CHROMIUM_REPO}
|
|
|
|
This script does following things;
|
|
- Clean existing libchrome code, except some manually created files and tools.
|
|
- Copy necessary files from original Chromium repository.
|
|
- Apply patches to the copied files, if necessary.
|
|
"""
|
|
|
|
|
|
import argparse
|
|
import fnmatch
|
|
import glob
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
|
|
|
|
_TOOLS_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
_LIBCHROME_ROOT = os.path.dirname(_TOOLS_DIR)
|
|
|
|
|
|
# Files in this list or in the directory listed here will be just copied.
|
|
# Paths ends with '/' is interpreted as directory.
|
|
_IMPORT_LIST = [
|
|
'mojo/',
|
|
'third_party/ply/',
|
|
'third_party/markupsafe/',
|
|
'third_party/jinja2/',
|
|
]
|
|
|
|
# Files which are in the repository, but should not be imported from Chrome
|
|
# repository.
|
|
_IMPORT_BLACKLIST = [
|
|
# Libchrome specific files.
|
|
'.gitignore',
|
|
'Android.bp',
|
|
'MODULE_LICENSE_BSD',
|
|
'NOTICE',
|
|
'OWNERS',
|
|
'SConstruct',
|
|
'libmojo.pc.in',
|
|
'testrunner.cc',
|
|
'*/DEPS',
|
|
|
|
# No Chromium OWNERS should be imported.
|
|
'*/OWNERS',
|
|
|
|
# libchrome_tools and soong are out of the update target.
|
|
'libchrome_tools/*',
|
|
'soong/*',
|
|
|
|
# No internal directories.
|
|
'mojo/internal/*',
|
|
|
|
# Those files should be generated. Please see also buildflag_header.patch.
|
|
'base/allocator/buildflags.h',
|
|
'base/android/java/src/org/chromium/base/BuildConfig.java',
|
|
'base/cfi_buildflags.h',
|
|
'base/debug/debugging_buildflags.h',
|
|
'base/memory/protected_memory_buildflags.h',
|
|
'base/synchronization/synchronization_buildflags.h',
|
|
'gen/*',
|
|
'ipc/ipc_buildflags.h',
|
|
|
|
# Blacklist several third party libraries; system libraries should be used.
|
|
'base/third_party/libevent/*',
|
|
'base/third_party/symbolize/*',
|
|
|
|
'testing/gmock/*',
|
|
'testing/gtest/*',
|
|
'third_party/ashmem/*',
|
|
'third_party/modp_b64/*',
|
|
'third_party/protobuf/*',
|
|
]
|
|
|
|
def _find_target_files(chromium_root):
|
|
"""Returns target files to be upreved."""
|
|
# Files in the repository should be updated.
|
|
output = subprocess.check_output(
|
|
['git', 'ls-tree', '-r', '--name-only', '--full-name', 'HEAD'],
|
|
cwd=_LIBCHROME_ROOT).decode('utf-8')
|
|
|
|
# Files in _IMPORT_LIST are copied in the following section, so
|
|
# exclude them from candidates, here, so that files deleted in chromium
|
|
# repository will be deleted on update.
|
|
candidates = [
|
|
path for path in output.splitlines()
|
|
if not any(path.startswith(import_path) for import_path in _IMPORT_LIST)]
|
|
|
|
# All files listed in _IMPORT_LIST should be imported, too.
|
|
for import_path in _IMPORT_LIST:
|
|
import_root = os.path.join(chromium_root, import_path)
|
|
|
|
# If it is a file, just add to the candidates.
|
|
if os.path.isfile(import_root):
|
|
candidates.append(import_path)
|
|
continue
|
|
|
|
# If it is a directory, traverse all files in the directory recursively
|
|
# and add all of them to candidates.
|
|
for dirpath, dirnames, filenames in os.walk(import_root):
|
|
for filename in filenames:
|
|
filepath = os.path.join(dirpath, filename)
|
|
candidates.append(os.path.relpath(filepath, chromium_root))
|
|
|
|
# Apply blacklist.
|
|
exclude_pattern = re.compile('|'.join(
|
|
'(?:%s)' % fnmatch.translate(pattern) for pattern in _IMPORT_BLACKLIST))
|
|
return [filepath for filepath in candidates
|
|
if not exclude_pattern.match(filepath)]
|
|
|
|
|
|
def _clean_existing_dir(output_root):
|
|
"""Removes existing libchrome files.
|
|
|
|
Args:
|
|
output_root: Path to the output directory.
|
|
"""
|
|
os.makedirs(output_root, mode=0o755, exist_ok=True)
|
|
for path in os.listdir(output_root):
|
|
target_path = os.path.join(output_root, path)
|
|
if (not os.path.isdir(target_path) or path in ('.git', 'libchrome_tools', 'soong')):
|
|
continue
|
|
shutil.rmtree(target_path)
|
|
|
|
|
|
def _import_files(chromium_root, output_root):
|
|
"""Copies files from Chromium repository into libchrome.
|
|
|
|
Args:
|
|
chromium_root: Path to the Chromium's repository.
|
|
output_root: Path to the output directory.
|
|
"""
|
|
for filepath in _find_target_files(chromium_root):
|
|
source_path = os.path.join(chromium_root, filepath)
|
|
target_path = os.path.join(output_root, filepath)
|
|
os.makedirs(os.path.dirname(target_path), mode=0o755, exist_ok=True)
|
|
shutil.copy2(source_path, target_path)
|
|
|
|
|
|
def _apply_patch_files(patch_root, output_root):
|
|
"""Applies patches.
|
|
|
|
libchrome needs some modification from Chromium repository, e.g. supporting
|
|
toolchain which is not used by Chrome, or using system library rather than
|
|
the library checked in the Chromium repository.
|
|
See each *.patch file in libchrome_tools/patch/ directory for details.
|
|
|
|
Args:
|
|
patch_root: Path to the directory containing patch files.
|
|
output_root: Path to the output directory.
|
|
"""
|
|
for patch_file in glob.iglob(os.path.join(patch_root, '*.patch')):
|
|
with open(patch_file, 'r') as f:
|
|
subprocess.check_call(['patch', '-p1'], stdin=f, cwd=output_root)
|
|
|
|
|
|
def _parse_args():
|
|
"""Parses commandline arguments."""
|
|
parser = argparse.ArgumentParser()
|
|
|
|
# TODO(hidehiko): Support to specify the Chromium's revision number.
|
|
parser.add_argument(
|
|
'--chromium_root',
|
|
help='Root directory to the local chromium repository.')
|
|
parser.add_argument(
|
|
'--output_root',
|
|
default=_LIBCHROME_ROOT,
|
|
help='Output directory, which is libchrome root directory.')
|
|
parser.add_argument(
|
|
'--patch_dir',
|
|
default=os.path.join(_TOOLS_DIR, 'patch'),
|
|
help='Directory containing patch files to be applied.')
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
args = _parse_args()
|
|
_clean_existing_dir(args.output_root)
|
|
_import_files(args.chromium_root, args.output_root)
|
|
_apply_patch_files(args.patch_dir, args.output_root)
|
|
# TODO(hidehiko): Create a git commit with filling templated message.
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|