gn2bp: Split `gcc_preprocess` actions into genrules
* It's not allowed to run `gcc` from within genrule in Soong. So It was an easier decision to create a cc_object and run it with a -E flag which is equivalent to what `gcc_preprocess` action does. Then perform a soong_zip on the result to generate the equivalent java file needed
Test: update_results && m cronet_aml_components_cronet_android_cronet
Change-Id: I1b2e50f1f95fbf700c1190902c716e624805a2b4
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
index f9ea631..42cb494 100755
--- a/tools/gn2bp/gen_android_bp
+++ b/tools/gn2bp/gen_android_bp
@@ -34,6 +34,7 @@
import re
import sys
import copy
+from pathlib import Path
import gn_utils
@@ -620,6 +621,53 @@
blueprint.add_module(module)
+def create_gcc_preprocess_modules(blueprint, target):
+ # gcc_preprocess.py internally execute host gcc which is not allowed in genrule.
+ # So, this function create multiple modules and realize equivalent processing
+ # TODO: Consider to support gcc_preprocess.py in different way
+ # It's not great to have genrule and cc_object in the dependency from java_library
+ assert (len(target.sources) == 1)
+ source = list(target.sources)[0]
+ assert (Path(source).suffix == '.template')
+ stem = Path(source).stem
+
+ bp_module_name = label_to_module_name(target.name)
+
+ # Rename .template to .cc since cc_object does not accept .template file as srcs
+ rename_module = Module('genrule', bp_module_name + '_rename', target.name)
+ rename_module.srcs.add(gn_utils.label_to_path(source))
+ rename_module.out.add(stem + '.cc')
+ rename_module.cmd = 'cp $(in) $(out)'
+ blueprint.add_module(rename_module)
+
+ # Preprocess template file and generates java file
+ preprocess_module = Module('cc_object', bp_module_name + '_preprocess', target.name)
+ # -E: stop after preprocessing.
+ # -P: disable line markers, i.e. '#line 309'
+ preprocess_module.cflags.update(['-E', '-P', '-DANDROID'])
+ preprocess_module.srcs.add(':' + rename_module.name)
+ defines = ['-D' + target.args[i+1] for i, arg in enumerate(target.args) if arg == '--define']
+ preprocess_module.cflags.update(defines)
+ # HACK: Specifying compile_multilib to build cc_object only once.
+ # Without this, soong complain to genrule that depends on cc_object when built for 64bit target.
+ # It seems this is because cc object is a module with per-architecture variants and genrule is a
+ # module with default variant. For 64bit target, cc_object is built multiple times for 32/64bit
+ # modes and genrule doesn't know which one to depend on.
+ preprocess_module.compile_multilib = 32
+ blueprint.add_module(preprocess_module)
+
+ # Generates srcjar using soong_zip
+ module = Module('genrule', bp_module_name, target.name)
+ module.srcs.add(':' + preprocess_module.name)
+ module.out.add(stem + '.srcjar')
+ module.cmd = NEWLINE.join([
+ f'cp $(in) $(genDir)/{stem}.java &&',
+ f'$(location soong_zip) -o $(out) -srcjar -f $(genDir)/{stem}.java'
+ ])
+ module.tools.add('soong_zip')
+ blueprint.add_module(module)
+ return module
+
class BaseActionSanitizer():
def __init__(self, target):
@@ -1255,7 +1303,11 @@
module = Module('java_library', bp_module_name, '//gn:java')
module.srcs.update([gn_utils.label_to_path(source) for source in gn.java_sources])
for dep in gn.java_actions:
- dep_module = create_action_module(blueprint, gn.get_target(dep), 'java_genrule')
+ target = gn.get_target(dep)
+ if target.script == '//build/android/gyp/gcc_preprocess.py':
+ module.srcs.add(':' + create_gcc_preprocess_modules(blueprint, target).name)
+ else:
+ module.srcs.add(':' + create_action_module(blueprint, target, 'java_genrule').name)
blueprint.add_module(module)
def update_jni_registration_module(module, gn):