Add a --copy-out flag for build.rs output files.
* When --copy-out is used: * copy build.rs output files to ./out * add a genrule module to copy ./out/* files to its output dir * add this copy-out genrule module into the srcs list This makes include! with $OUT_DIR path work without local patch. This only works for the root directory (package). * Upgrade to python3 for some required shutil and glob functions. * Unified dump_srcs_list for defaults and non-defaults modules. * dump_android_property_list output only one line for a single item list. Bug: 171659849 Test: regenerate all .bp files in rust/crates/* Change-Id: Ia7dde0ccede2bcc068f23a046e85304c6f50b0b0
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) 2019 The Android Open Source Project
|
||||
#
|
||||
@@ -49,10 +49,12 @@ a warning comment to the owner crate module in Android.bp.
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import os
|
||||
import os.path
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
# Some Rust packages include extra unwanted crates.
|
||||
@@ -593,6 +595,17 @@ class Crate(object):
|
||||
return name3
|
||||
return self.runner.claim_module_name(name1, self, 0)
|
||||
|
||||
def dump_srcs_list(self):
|
||||
"""Dump the srcs list, for defaults or regular modules."""
|
||||
if len(self.srcs) > 1:
|
||||
srcs = sorted(set(self.srcs)) # make a copy and dedup
|
||||
else:
|
||||
srcs = [self.main_src]
|
||||
copy_out = self.runner.copy_out_module_name()
|
||||
if copy_out:
|
||||
srcs.append(':' + copy_out)
|
||||
self.dump_android_property_list('srcs', '"%s"', srcs)
|
||||
|
||||
def dump_defaults_module(self):
|
||||
"""Dump a rust_defaults module to be shared by other modules."""
|
||||
name = self.build_default_name()
|
||||
@@ -606,7 +619,7 @@ class Crate(object):
|
||||
self.default_srcs = True
|
||||
if self.has_warning and not self.cap_lints:
|
||||
self.write(' // has rustc warnings')
|
||||
self.write(' srcs: ["' + self.main_src + '"],')
|
||||
self.dump_srcs_list()
|
||||
if 'test' in self.crate_types:
|
||||
self.write(' test_suites: ["general-tests"],')
|
||||
self.write(' auto_gen_config: true,')
|
||||
@@ -769,10 +782,15 @@ class Crate(object):
|
||||
self.write(' ' + (fmt % escape_quotes(v)) + ',')
|
||||
|
||||
def dump_android_property_list(self, name, fmt, values):
|
||||
if values:
|
||||
if not values:
|
||||
return
|
||||
if len(values) > 1:
|
||||
self.write(' ' + name + ': [')
|
||||
self.dump_android_property_list_items(fmt, values)
|
||||
self.write(' ],')
|
||||
else:
|
||||
self.write(' ' + name + ': [' +
|
||||
(fmt % escape_quotes(values[0])) + '],')
|
||||
|
||||
def dump_android_core_properties(self):
|
||||
"""Dump the module header, name, stem, etc."""
|
||||
@@ -790,11 +808,8 @@ class Crate(object):
|
||||
self.write(' host_supported: true,')
|
||||
if not self.defaults:
|
||||
self.write(' crate_name: "' + self.crate_name + '",')
|
||||
if len(self.srcs) > 1:
|
||||
self.srcs = sorted(set(self.srcs))
|
||||
self.dump_android_property_list('srcs', '"%s"', self.srcs)
|
||||
elif not self.default_srcs:
|
||||
self.write(' srcs: ["' + self.main_src + '"],')
|
||||
if not self.default_srcs:
|
||||
self.dump_srcs_list()
|
||||
if 'test' in self.crate_types and not self.defaults:
|
||||
# self.root_pkg can have multiple test modules, with different *_tests[n]
|
||||
# names, but their executables can all be installed under the same _tests
|
||||
@@ -1021,6 +1036,8 @@ class Runner(object):
|
||||
self.dry_run = not args.run
|
||||
self.skip_cargo = args.skipcargo
|
||||
self.cargo_path = './cargo' # path to cargo, will be set later
|
||||
self.checked_out_files = False # to check only once
|
||||
self.build_out_files = [] # output files generated by build.rs
|
||||
# All cc/ar objects, crates, dependencies, and warning files
|
||||
self.cc_objects = list()
|
||||
self.pkg_obj2cc = {}
|
||||
@@ -1099,11 +1116,56 @@ class Runner(object):
|
||||
rust_version = version
|
||||
return '.'.join(rust_version)
|
||||
|
||||
def copy_out_files(self):
|
||||
"""Copy build.rs output files to ./out and set up build_out_files."""
|
||||
if not self.args.copy_out or self.checked_out_files:
|
||||
return
|
||||
self.checked_out_files = True
|
||||
# list1 has build.rs output for normal crates
|
||||
list1 = glob.glob(TARGET_TMP + '/*/*/build/' + self.root_pkg + '-*/out/*')
|
||||
# list2 has build.rs output for proc-macro crates
|
||||
list2 = glob.glob(TARGET_TMP + '/*/build/' + self.root_pkg + '-*/out/*')
|
||||
out_files = set()
|
||||
if list1 or list2:
|
||||
os.makedirs('out', exist_ok=True)
|
||||
for path in (list1 + list2):
|
||||
file_name = path.split('/')[-1]
|
||||
out_files.add(file_name)
|
||||
shutil.copy(path, 'out/' + file_name)
|
||||
self.build_out_files = sorted(out_files)
|
||||
|
||||
def copy_out_module_name(self):
|
||||
if self.args.copy_out and self.build_out_files:
|
||||
return 'copy_' + self.root_pkg + '_build_out'
|
||||
else:
|
||||
return ''
|
||||
|
||||
def dump_copy_out_module(self, outf):
|
||||
"""Output the genrule module to copy out/* to $(genDir)."""
|
||||
copy_out = self.copy_out_module_name()
|
||||
if not copy_out:
|
||||
return
|
||||
outf.write('\ngenrule {\n')
|
||||
outf.write(' name: "' + copy_out + '",\n')
|
||||
outf.write(' srcs: ["out/*"],\n')
|
||||
outf.write(' cmd: "cp $(in) $(genDir)",\n')
|
||||
if len(self.build_out_files) > 1:
|
||||
outf.write(' out: [\n')
|
||||
for f in self.build_out_files:
|
||||
outf.write(' "' + f + '",\n')
|
||||
outf.write(' ],\n')
|
||||
else:
|
||||
outf.write(' out: ["' + self.build_out_files[0] + '"],\n')
|
||||
outf.write('}\n')
|
||||
|
||||
def init_bp_file(self, name):
|
||||
# name could be Android.bp or sub_dir_path/Android.bp
|
||||
if name not in self.bp_files:
|
||||
self.bp_files.add(name)
|
||||
with open(name, 'w') as outf:
|
||||
outf.write(ANDROID_BP_HEADER.format(args=' '.join(sys.argv[1:])))
|
||||
# at most one copy_out module per .bp file
|
||||
self.dump_copy_out_module(outf)
|
||||
|
||||
def dump_test_mapping_files(self):
|
||||
"""Dump all TEST_MAPPING files."""
|
||||
@@ -1248,6 +1310,7 @@ class Runner(object):
|
||||
print('Dry-run skip: read', CARGO_OUT, 'write Android.bp')
|
||||
elif os.path.exists(CARGO_OUT):
|
||||
self.find_root_pkg()
|
||||
self.copy_out_files()
|
||||
with open(CARGO_OUT, 'r') as cargo_out:
|
||||
self.parse(cargo_out, 'Android.bp')
|
||||
self.crates.sort(key=get_module_name)
|
||||
@@ -1401,6 +1464,14 @@ def parse_args():
|
||||
'--cargo_bin',
|
||||
type=str,
|
||||
help='use cargo in the cargo_bin directory instead of the prebuilt one')
|
||||
parser.add_argument(
|
||||
'--copy-out',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=('only for root directory, ' +
|
||||
'copy build.rs output to ./out/* and add a genrule to copy ' +
|
||||
'./out/* to genrule output; for crates with code pattern: ' +
|
||||
'include!(concat!(env!("OUT_DIR"), "/<some_file>.rs"))'))
|
||||
parser.add_argument(
|
||||
'--debug',
|
||||
action='store_true',
|
||||
|
||||
Reference in New Issue
Block a user