1#!/usr/bin/env python3 2""" 3This script can be used to generate LIC_FILES_CHKSUM in chromium.inc. 4 5It uses Chromium's own tools/licenses/licenses.py script to scan for third_party 6directories and license files. This means its output is generated on a 7best-effort basis, as some directories are non-compliant upstream or may not be 8found. It might also include directories which are not used in a 9Yocto/OpenEmbedded build. 10""" 11 12import argparse 13import hashlib 14import os 15import sys 16 17# These are directories that are known to cause licenses.LicenseError to be 18# thrown because but should not cause a failure in this script for 19# different reasons. 20SKIPPED_DIRECTORIES = ( 21 # These directories are not part of the Chromium tarballs (upstream's 22 # export_tarball.py declares them "non-essential" or plain test 23 # directories, and their README.chromium in the git repositories mark 24 # them as NOT_SHIPPED). 25 'chrome/test/data', 26 'third_party/hunspell_dictionaries', 27 28 # android_protobuf is checked out and used only in Android builds, so a 29 # LicenseError will be thrown because README.chromium will point to a 30 # file that is not present in a Chromium tarball. 31 'third_party/android_protobuf', 32 33 # Starting with M61, Chromium is shipping its own pinned version of 34 # depot_tools. It's only part of the build and the directory structure 35 # does not follow the standard. Skip it. 36 'third_party/depot_tools', 37 38 # M63 and later: we do not consume win_build_output. 39 'third_party/win_build_output', 40 41 # M67: third_party/fuchsia-sdk has no LICENSE file. This is not used in 42 # Linux builds though. 43 # https://bugs.chromium.org/p/chromium/issues/detail?id=847821 44 'third_party/fuchsia-sdk', 45) 46 47 48def find_chromium_licenses(chromium_root): 49 """Look for license files in a Chromium checkout and return a set with all 50 files that are actually shipped and used in the final Chromium binary.""" 51 try: 52 import licenses 53 except ImportError: 54 raise ImportError('Failed to import licenses.py. Make sure %s ' 55 'contains tools/licenses/licenses.py.' % chromium_root) 56 57 # Make sure the main Chromium LICENSE file is always present. 58 license_files = set([os.path.join(chromium_root, 'LICENSE')]) 59 60 for d in licenses.FindThirdPartyDirs(licenses.PRUNE_PATHS, chromium_root): 61 if d in SKIPPED_DIRECTORIES: 62 continue 63 try: 64 metadata = licenses.ParseDir(d, chromium_root) 65 except licenses.LicenseError as e: 66 print('Exception in directory %s: %s' % (d, e)) 67 if input('Ignore (y)? ') == 'y': 68 continue 69 raise 70 # We are not interested in licenses for projects that are not marked as 71 # used in the final product (ie. they might be optional development 72 # aids, or only used in a build). 73 if metadata['License File'] != licenses.NOT_SHIPPED: 74 license_files.add(metadata['License File']) 75 return license_files 76 77 78def print_license_list(chromium_root, output_file): 79 """Print a list of Chromium license paths and checksums in a format 80 suitable for use in a Yocto recipe.""" 81 licenses = {} 82 for license_file in find_chromium_licenses(chromium_root): 83 with open(license_file, 'rb') as file_handle: 84 license_hash = hashlib.md5(file_handle.read()).hexdigest() 85 license_relpath = os.path.relpath(license_file, chromium_root) 86 licenses[license_relpath] = license_hash 87 with open(output_file, 'w') as out: 88 out.write('LIC_FILES_CHKSUM = "\\\n') 89 for f in sorted(licenses): 90 out.write(' file://${S}/%s;md5=%s \\\n' % (f, licenses[f])) 91 out.write(' "\n') 92 93 94if __name__ == '__main__': 95 parser = argparse.ArgumentParser() 96 parser.add_argument('chromium_root', 97 help='Path to the root directory of a Chromium ' 98 'checkout or extracted tarball.') 99 parser.add_argument('output_file', 100 help='File to write the output to (it will be ' 101 'overwritten)') 102 args = parser.parse_args() 103 104 tools_licenses_dir = os.path.join(args.chromium_root, 'tools/licenses') 105 if not os.path.isdir(tools_licenses_dir): 106 print('%s does not look like a valid directory.' % tools_licenses_dir) 107 sys.exit(1) 108 sys.path = [tools_licenses_dir] + sys.path 109 110 print_license_list(args.chromium_root, args.output_file) 111