def run_convert(args): # Check that the fuchsia.git tree is clean. if not is_tree_clean(): return 1 # Identify the affected build files. build_files = locate_build_files(args.binary) if not build_files: print('Error: could not find any files for ' + args.binary) return 1 # Confirm with the user that these are the files they want to convert. print('The following build file(s) will be converted:') for file in build_files: print(' - ' + os.path.relpath(file, FUCHSIA_ROOT)) go_ahead = raw_input('Proceed? (Y/n) ').lower().strip() if go_ahead != 'y' and go_ahead != '': print('User disagrees, exiting') return 0 # Determine what branch to start from. branch_args = ['JIRI_HEAD'] if args.from_current_branch: head = run_command(['git', 'symbolic-ref', '--short', '-q', 'HEAD']).strip() if not head.startswith(BRANCH_PREFIX): print('Error: should start from a migration branch (i.e. named "%sfoo").' % BRANCH_PREFIX) return 1 branch_args = ['-t', head] # Convert the build files. for file in build_files: transform_build_file(file) # Create a commit. id = args.binary.replace('/', '_') run_command(['git', 'checkout', '-b', BRANCH_PREFIX + id] + branch_args) run_command(['git', 'add', '.']) message = [ '[unification] Move //zircon/system/' + args.binary + ' to the GN build', '', 'Generated with: ' + SCRIPT_LABEL, '', 'scripts/unification/verify_element_move.py --reference local/initial.json:', 'TODO PASTE VERIFICATION RESULT HERE', '', 'Bug: 36139' ] commit_command = ['git', 'commit', '-a'] for line in message: commit_command += ['-m', line] run_command(commit_command) print('Base change is ready. Please attempt to build a full system to ' 'identify further required changes.') return 0
def main(): parser = argparse.ArgumentParser( description='Moves a C/C++ library from //zircon to //sdk') parser.add_argument('--lib', help='Name of the library folder to migrate, e.g. ' 'ulib/foo or dev/lib/bar', action='append') args = parser.parse_args() if not args.lib: print('Need to specify at least one library.') return 1 # Check that the fuchsia.git tree is clean. if not is_tree_clean(): return 1 movable_libs = [] for lib in args.lib: # Verify that the library may be migrated at this time. library = Library(lib) if not os.path.exists(library.build_path): print('Could not locate library ' + lib + ', ignoring') continue # No kernel! if library.has_kernel: print('Some libraries are used in the kernel and may not be ' 'migrated at the moment, ignoring ' + lib) continue # Only libraries that have been exported to the GN build already! if library.has_unexported: print( 'Can only convert libraries already exported to the GN build,' ' ignoring ' + lib) continue # No SDK libraries for now. if library.has_sdk and library.has_static: print('Cannot convert static SDK libraries for now, ignoring ' + lib) continue # Gather build files with references to the library. for base, _, files in os.walk(FUCHSIA_ROOT): for file in files: if file != 'BUILD.gn': continue file_path = os.path.join(base, file) with open(file_path, 'r') as build_file: content = build_file.read() for name in [s.name for s in library.stats]: reference = '"//zircon/public/lib/' + name + '"' if reference in content: library.build_files.append(file_path) if not is_in_fuchsia_project(file_path): library.cross_project = True break movable_libs.append(library) if not movable_libs: print('Could not find any library to convert, aborting') return 1 solo_libs = [ l.name for l in movable_libs if l.cross_project or l.has_shared ] if solo_libs and len(movable_libs) > 1: print('These libraries may only be moved in a dedicated change: ' + ', '.join(solo_libs)) return 1 for library in movable_libs: # Rewrite the library's build file. import_added = False for line in fileinput.FileInput(library.build_path, inplace=True): # Remove references to libzircon. if '$zx/system/ulib/zircon' in line and not 'zircon-internal' in line: line = '' # Update references to libraries. line = line.replace('$zx/system/ulib', '//zircon/public/lib') line = line.replace('$zx/system/dev/lib', '//zircon/public/lib') # Update known configs. line = line.replace( '$zx_build/public/gn/config:static-libc++', '//build/config/fuchsia:static_cpp_standard_library') # Update references to Zircon in general. line = line.replace('$zx', '//zircon') # Update deps on libdriver. line = line.replace('//zircon/public/lib/driver', '//src/devices/lib/driver') # Remove header target specifier. line = line.replace('.headers', '') line = line.replace(':headers', '') sys.stdout.write(line) if not line.strip() and not import_added: import_added = True sys.stdout.write( '##########################################\n') sys.stdout.write( '# Though under //zircon, this build file #\n') sys.stdout.write( '# is meant to be used in the Fuchsia GN #\n') sys.stdout.write( '# build. #\n') sys.stdout.write( '# See fxb/36548. #\n') sys.stdout.write( '##########################################\n') sys.stdout.write('\n') sys.stdout.write( 'assert(!defined(zx) || zx != "/", "This file can only be used in the Fuchsia GN build.")\n' ) sys.stdout.write('\n') sys.stdout.write( 'import("//build/unification/zx_library.gni")\n') sys.stdout.write('\n') fx_format(library.build_path) # Edit references to the library. for file_path in library.build_files: for line in fileinput.FileInput(file_path, inplace=True): for name in [s.name for s in library.stats]: new_label = '"' + library.base_label if os.path.basename(new_label) != name: new_label = new_label + ':' + name new_label = new_label + '"' line = re.sub('"//zircon/public/lib/' + name + '"', new_label, line) sys.stdout.write(line) fx_format(file_path) # Remove references to the library in the unification scaffolding if # necessary. if library.has_shared: unification_path = os.path.join(FUCHSIA_ROOT, 'build', 'unification', 'images', 'BUILD.gn') def unification_replacer(line): for name in [s.name for s in library.stats]: if re.match('^\s*"' + name + '",$', line): # Remove the line. return '' replace_lines(unification_path, unification_replacer) # Generate an alias for the library under //zircon/public/lib if a soft # transition is necessary. if library.cross_project: alias_path = os.path.join(FUCHSIA_ROOT, 'build', 'unification', 'zircon_library_mappings.json') with open(alias_path, 'r') as alias_file: data = json.load(alias_file) for s in library.stats: data.append({ 'name': s.name, 'sdk': s.sdk_publishable, 'label': library.base_label + ":" + s.name, }) data = sorted(data, key=lambda item: item['name']) with open(alias_path, 'w') as alias_file: json.dump(data, alias_file, indent=2, sort_keys=True, separators=(',', ': ')) # Update references to the library if it belongs to any SDK. if library.has_sdk: sdk_path = os.path.join(FUCHSIA_ROOT, 'sdk', 'BUILD.gn') folder = os.path.basename(library.name) def sdk_replacer(line): for name in [s.name for s in library.stats]: if '"//zircon/public/lib/' + folder + ':' + name + '_sdk' + '"' in line: return line.replace('public/lib', 'system/ulib') replace_lines(sdk_path, sdk_replacer) fx_format(sdk_path) # Remove the reference in the ZN aggregation target. aggregation_path = os.path.join(FUCHSIA_ROOT, 'zircon', 'system', os.path.dirname(library.name), 'BUILD.gn') if os.path.exists(aggregation_path): folder = os.path.basename(library.name) def aggregation_replacer(line): for name in [s.name for s in library.stats]: if ('"' + folder + ':' + name + '"' in line or '"' + folder + '"' in line): return '' replace_lines(aggregation_path, aggregation_replacer) else: print('Warning: some references to ' + lib + ' might still exist ' 'in the ZN build, please remove them manually') # Create a commit. libs = sorted([l.name for l in movable_libs]) under_libs = [l.replace('/', '_') for l in libs] branch_name = 'lib-move-' + under_libs[0] lib_name = '//zircon/system/' + libs[0] if len(libs) > 1: branch_name += '-and-co' lib_name += ' and others' run_command(['git', 'checkout', '-b', branch_name, 'JIRI_HEAD']) run_command(['git', 'add', FUCHSIA_ROOT]) message = [ '[unification] Move ' + lib_name + ' to the GN build', '', 'Affected libraries:' ] + ['//zircon/system/' + l for l in libs] if any(l.has_shared for l in movable_libs): message += [ '', 'scripts/unification/verify_element_move.py --reference local/initial.json:', '', 'TODO PASTE VERIFICATION RESULT HERE', ] message += ['', 'Generated with ' + SCRIPT_LABEL, '', 'Bug: 36548'] fd, message_path = tempfile.mkstemp() with open(message_path, 'w') as message_file: message_file.write('\n'.join(message)) commit_command = ['git', 'commit', '-a', '-F', message_path] run_command(commit_command) os.close(fd) os.remove(message_path) if any(l.cross_project for l in movable_libs): print('*** Warning: multiple Git projects were affected by this move!') print('Run jiri status to view affected projects.') print('Staging procedure:') print( ' - use "jiri upload" to start the review process on the fuchsia.git change;' ) print( ' - prepare dependent CLs for each affected project and get them review;' ) print( ' - when the fuchsia.git change has rolled into GI, get the other CLs submitted;' ) print( ' - when these CLs have rolled into GI, prepare a change to remove the forwarding' ) print( ' targets under //build/unification/zircon_library_mappings.json' ) else: print( 'Change is ready, use "jiri upload" to start the review process.') return 0
def main(): parser = argparse.ArgumentParser( description='Moves a Banjo library from //zircon to //sdk') parser.add_argument('lib', help='Name of the library to migrate') args = parser.parse_args() lib = args.lib # Check that the fuchsia.git tree is clean. if not is_tree_clean(): return 1 sdk_base = os.path.join(FUCHSIA_ROOT, 'sdk', 'banjo') sdk_dir = os.path.join(sdk_base, lib) banjo_base = os.path.join(FUCHSIA_ROOT, 'zircon', 'system', 'banjo') source_dir = os.path.join(banjo_base, lib) # Move the sources. shutil.move(source_dir, sdk_base) # Edit the build file. is_dummy = not (lib.startswith('ddk.protocol') or lib.startswith('ddk.hw')) build_path = os.path.join(sdk_dir, 'BUILD.gn') for line in fileinput.FileInput(build_path, inplace=True): line = line.replace('$zx_build/public/gn/banjo.gni', '//build/banjo/banjo.gni') line = line.replace('banjo_library', 'banjo_dummy' if is_dummy else 'banjo') line = line.replace('public_deps', 'deps') line = line.replace('$zx/system/banjo', '//zircon/system/banjo') sys.stdout.write(line) fx_format(build_path) # Edit references to the library. for base, _, files in os.walk(FUCHSIA_ROOT): for file in files: if file != 'BUILD.gn': continue file_path = os.path.join(base, file) has_changes = False for original_line in fileinput.FileInput(file_path, inplace=True): # Make sure that only exact matches are replaced, as some # library names are prefix of other names. # Examples: # //zircon/s/b/ddk.foo.bar" --> "//sdk/b/foo.bar" # //zircon/s/b/ddk.foo.bar:boop" --> "//sdk/b/foo.bar:boop" line = re.sub('"(//zircon/system/banjo/' + lib + ')([:"])', '"//sdk/banjo/' + lib + '\\2', original_line) if line != original_line: has_changes = True sys.stdout.write(line) if has_changes: fx_format(file_path) for line in fileinput.FileInput(os.path.join(banjo_base, 'BUILD.gn'), inplace=True): if not '"' + lib + '"' in line: sys.stdout.write(line) # Create a commit. run_command(['git', 'checkout', '-b', 'banjo-move-' + lib, 'JIRI_HEAD']) run_command(['git', 'add', sdk_dir]) message = [ '[unification] Move ' + lib + ' to //sdk/banjo', '', 'Generated with: //scripts/unification/move_banjo_library.py ' + lib, '', 'Bug: 36540' ] commit_command = ['git', 'commit', '-a'] for line in message: commit_command += ['-m', line] run_command(commit_command) print('Change is ready, use "jiri upload" to start the review process.') return 0
def main(): parser = argparse.ArgumentParser( description='Moves a C/C++ library from //zircon to //sdk') parser.add_argument('lib', help='Name of the library folder to migrate, e.g. ' 'ulib/foo or dev/lib/bar') args = parser.parse_args() # Check that the fuchsia.git tree is clean. if not is_tree_clean(): return 1 # Verify that the library may be migrated at this time. build_path = os.path.join(FUCHSIA_ROOT, 'zircon', 'system', args.lib, 'BUILD.gn') base_label = '//zircon/system/' + args.lib stats = get_library_stats(build_path) # No kernel! has_kernel = len([s for s in stats if s.kernel]) != 0 if has_kernel: print('Some libraries in the given folder are used in the kernel and ' 'may not be migrated at the moment') return 1 # Only source libraries! non_source_sdk = len([s for s in stats if s.sdk != Sdk.SOURCE]) != 0 if non_source_sdk: print('Can only convert libraries exported as "sources" for now') return 1 # Rewrite the library's build file. import_added = False for line in fileinput.FileInput(build_path, inplace=True): # Remove references to libzircon. if '$zx/system/ulib/zircon' in line and not 'zircon-internal' in line: line = '' # Update references to libraries. line = line.replace('$zx/system/ulib', '//zircon/public/lib') line = line.replace('$zx/system/dev/lib', '//zircon/public/lib') # Update known configs. line = line.replace( '$zx_build/public/gn/config:static-libc++', '//build/config/fuchsia:static_cpp_standard_library') # Update references to Zircon in general. line = line.replace('$zx', '//zircon') # Update deps on libdriver. line = line.replace('//zircon/public/lib/driver', '//src/devices/lib/driver') # Remove header target specifier. line = line.replace('.headers', '') line = line.replace(':headers', '') sys.stdout.write(line) if not line.strip() and not import_added: import_added = True sys.stdout.write('##########################################\n') sys.stdout.write('# Though under //zircon, this build file #\n') sys.stdout.write('# is meant to be used in the Fuchsia GN #\n') sys.stdout.write('# build. #\n') sys.stdout.write('# See fxb/36548. #\n') sys.stdout.write('##########################################\n') sys.stdout.write('\n') sys.stdout.write( 'assert(!defined(zx) || zx != "/", "This file can only be used in the Fuchsia GN build.")\n' ) sys.stdout.write('\n') sys.stdout.write('import("//build/unification/zx_library.gni")\n') sys.stdout.write('\n') fx_format(build_path) # Track whether fuchsia.git was the only affected project. multiple_projects_affected = False # Edit references to the library. for base, _, files in os.walk(FUCHSIA_ROOT): for file in files: if file != 'BUILD.gn': continue has_matches = False file_path = os.path.join(base, file) for line in fileinput.FileInput(file_path, inplace=True): for name in [s.name for s in stats]: new_label = '"' + base_label if os.path.basename(new_label) != name: new_label = new_label + ':' + name new_label = new_label + '"' line, count = re.subn('"//zircon/public/lib/' + name + '"', new_label, line) if count: has_matches = True sys.stdout.write(line) if has_matches: fx_format(file_path) if not is_in_fuchsia_project(file_path): multiple_projects_affected = True # Generate an alias for the library under //zircon/public/lib if a soft # transition is necessary. if multiple_projects_affected: alias_path = os.path.join(FUCHSIA_ROOT, 'build', 'unification', 'zircon_library_mappings.json') with open(alias_path, 'r') as alias_file: data = json.load(alias_file) for s in stats: data.append({ 'name': s.name, 'sdk': s.sdk_publishable, 'label': base_label + ":" + s.name, }) data = sorted(data, key=lambda item: item['name']) with open(alias_path, 'w') as alias_file: json.dump(data, alias_file, indent=2, sort_keys=True, separators=(',', ': ')) # Remove the reference in the ZN aggregation target. aggregation_path = os.path.join(FUCHSIA_ROOT, 'zircon', 'system', os.path.dirname(args.lib), 'BUILD.gn') folder = os.path.basename(args.lib) for line in fileinput.FileInput(aggregation_path, inplace=True): for s in stats: if (not '"' + folder + ':' + name + '"' in line and not '"' + folder + '"' in line): sys.stdout.write(line) # Create a commit. lib = args.lib.replace('/', '_') run_command(['git', 'checkout', '-b', 'lib-move-' + lib, 'JIRI_HEAD']) run_command(['git', 'add', FUCHSIA_ROOT]) message = [ '[unification] Move //zircon/system/' + args.lib + ' to the GN build', '', 'Generated with: ' + SCRIPT_LABEL + ' ' + args.lib, '', 'Bug: 36548' ] commit_command = ['git', 'commit', '-a'] for line in message: commit_command += ['-m', line] run_command(commit_command) if multiple_projects_affected: print('*** Warning: multiple Git projects were affected by this move!') print('Run jiri status to view affected projects.') print('Staging procedure:') print( ' - use "jiri upload" to start the review process on the fuchsia.git change;' ) print( ' - prepare dependent CLs for each affected project and get them review;' ) print( ' - when the fuchsia.git change has rolled into GI, get the other CLs submitted;' ) print( ' - when these CLs have rolled into GI, prepare a change to remove the forwarding' ) print( ' targets under //build/unification/zircon_library_mappings.json' ) else: print( 'Change is ready, use "jiri upload" to start the review process.') return 0
def main(): parser = argparse.ArgumentParser( description='Moves a FIDL library from //zircon to //sdk') parser.add_argument('lib', help='Name of the library to migrate') args = parser.parse_args() # Accept library names with dots or dashes. lib = args.lib.replace('-', '.') lib_with_dash = args.lib.replace('.', '-') # Check that the fuchsia.git tree is clean. if not is_tree_clean(): return 1 sdk_base = os.path.join(FUCHSIA_ROOT, 'sdk', 'fidl') sdk_dir = os.path.join(sdk_base, lib) fidl_base = os.path.join(FUCHSIA_ROOT, 'zircon', 'system', 'fidl') source_dir = os.path.join(fidl_base, lib_with_dash) # Move the sources. # The destination directory sometimes already exists. if not os.path.isdir(sdk_dir): os.mkdir(sdk_dir) for _, _, files in os.walk(source_dir): for file in files: shutil.move(os.path.join(source_dir, file), sdk_dir) dest_file = os.path.join(sdk_dir, file) fx_format(dest_file) break # Edit the build file in its new location. in_sdk = False build_path = os.path.join(sdk_dir, 'BUILD.gn') for line in fileinput.FileInput(build_path, inplace=True): if 'sdk = false' in line: continue if 'sdk = true' in line: in_sdk = True print(' sdk_category = "partner"') print(' api = "' + lib + '.api"') continue line = line.replace('$zx_build/public/gn/fidl.gni', '//build/fidl/fidl.gni') line = line.replace('fidl_library', 'fidl') line = line.replace(lib_with_dash, lib) line = line.replace('$zx/system/fidl', '//zircon/system/fidl') sys.stdout.write(line) fx_format(build_path) # Track whether fuchsia.git was the only affected project. multiple_projects_affected = False # Edit references to the library. for base, _, files in os.walk(FUCHSIA_ROOT): for file in files: if file != 'BUILD.gn': continue has_matches = False file_path = os.path.join(base, file) for line in fileinput.FileInput(file_path, inplace=True): match = re.search( '"//zircon/system/fidl/' + lib_with_dash + '(?::(?P<target>[^"]+))?"', line) if match: has_matches = True original_target = match.group('target') if original_target: if original_target == 'c': target = lib + '_c' elif original_target == 'c.headers': target = lib + '_c' elif original_target == 'llcpp': target = lib + '_llcpp' elif original_target == 'llcpp.headers': target = lib + '_llcpp' else: target = original_target.replace( lib_with_dash, lib) line = line.replace( '"//zircon/system/fidl/' + lib_with_dash + ':' + original_target + '"', '"//sdk/fidl/' + lib + ':' + target + '"') else: line = line.replace( '"//zircon/system/fidl/' + lib_with_dash + '"', '"//sdk/fidl/' + lib + '"') sys.stdout.write(line) if has_matches: # Format the file. fx_format(file_path) if not is_in_fuchsia_project(file_path): multiple_projects_affected = True if multiple_projects_affected: # Set up an alias in the old location. with open(os.path.join(source_dir, 'BUILD.gn'), 'w') as build_file: build_file.writelines([ '# Copyright 2020 The Fuchsia Authors. All rights reserved.\n', '# Use of this source code is governed by a BSD-style license that can be\n', '# found in the LICENSE file.\n', '\n', 'import("//build/unification/fidl_alias.gni")\n', '\n', 'fidl_alias("%s") {\n' % lib_with_dash, ' sdk_category = "partner"\n' if in_sdk else '\n', '}\n', ]) # Edit references to the library. # Only editing the ZN file listing all FIDL libraries. for line in fileinput.FileInput(os.path.join(fidl_base, 'BUILD.gn'), inplace=True): if not '"' + lib_with_dash + '"' in line: sys.stdout.write(line) # Create a commit. run_command(['git', 'checkout', '-b', 'fidl-move-' + lib, 'JIRI_HEAD']) run_command(['git', 'add', sdk_dir]) message = [ '[unification] Move ' + lib + ' to //sdk/fidl', '', 'Generated with: //scripts/unification/move_fidl_library.py ' + lib, '', 'Bug: 36547' ] commit_command = ['git', 'commit', '-a'] for line in message: commit_command += ['-m', line] run_command(commit_command) if multiple_projects_affected: print('*** Warning: multiple Git projects were affected by this move!') print('Run jiri status to view affected projects.') print('Staging procedure:') print( ' - use "jiri upload" to start the review process on the fuchsia.git change;' ) print( ' - prepare dependent CLs for each affected project and get them review;' ) print( ' - when the fuchsia.git change has rolled into GI, get the other CLs submitted;' ) print( ' - when these CLs have rolled into GI, prepare a change to remove the forwarding' ) print(' target under //zircon/system/fidl/' + lib_with_dash) else: print( 'Change is ready, use "jiri upload" to start the review process.') return 0