Make javac and jar a single build action
This allows us to more accurately specify the outputs of each action (we can't specify the .class file outputs easily because determing them essentially requires compiling the .java files). The lint action still operates directly on the .class files, so we continue to support specifying a directory for the .class files (but in a very simple to remove way). BUG=359249 Review URL: https://codereview.chromium.org/328893003 git-svn-id: http://src.chromium.org/svn/trunk/src/build@279152 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
Родитель
d5cac44d70
Коммит
cf328cf8da
|
@ -12,32 +12,36 @@ import sys
|
||||||
from util import build_utils
|
from util import build_utils
|
||||||
from util import md5_check
|
from util import md5_check
|
||||||
|
|
||||||
|
def Jar(class_files, classes_dir, jar_path):
|
||||||
def DoJar(options):
|
jar_path = os.path.abspath(jar_path)
|
||||||
class_files = build_utils.FindInDirectory(options.classes_dir, '*.class')
|
|
||||||
for exclude in build_utils.ParseGypList(options.excluded_classes):
|
|
||||||
class_files = filter(
|
|
||||||
lambda f: not fnmatch.fnmatch(f, exclude), class_files)
|
|
||||||
|
|
||||||
jar_path = os.path.abspath(options.jar_path)
|
|
||||||
|
|
||||||
# The paths of the files in the jar will be the same as they are passed in to
|
# The paths of the files in the jar will be the same as they are passed in to
|
||||||
# the command. Because of this, the command should be run in
|
# the command. Because of this, the command should be run in
|
||||||
# options.classes_dir so the .class file paths in the jar are correct.
|
# options.classes_dir so the .class file paths in the jar are correct.
|
||||||
jar_cwd = options.classes_dir
|
jar_cwd = classes_dir
|
||||||
class_files_rel = [os.path.relpath(f, jar_cwd) for f in class_files]
|
class_files_rel = [os.path.relpath(f, jar_cwd) for f in class_files]
|
||||||
jar_cmd = ['jar', 'cf0', jar_path] + class_files_rel
|
jar_cmd = ['jar', 'cf0', jar_path] + class_files_rel
|
||||||
|
|
||||||
record_path = '%s.md5.stamp' % options.jar_path
|
record_path = '%s.md5.stamp' % jar_path
|
||||||
md5_check.CallAndRecordIfStale(
|
md5_check.CallAndRecordIfStale(
|
||||||
lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
|
lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
|
||||||
record_path=record_path,
|
record_path=record_path,
|
||||||
input_paths=class_files,
|
input_paths=class_files,
|
||||||
input_strings=jar_cmd)
|
input_strings=jar_cmd,
|
||||||
|
force=not os.path.exists(jar_path),
|
||||||
|
)
|
||||||
|
|
||||||
build_utils.Touch(options.jar_path)
|
build_utils.Touch(jar_path, fail_if_missing=True)
|
||||||
|
|
||||||
|
|
||||||
|
def JarDirectory(classes_dir, excluded_classes, jar_path):
|
||||||
|
class_files = build_utils.FindInDirectory(classes_dir, '*.class')
|
||||||
|
for exclude in excluded_classes:
|
||||||
|
class_files = filter(
|
||||||
|
lambda f: not fnmatch.fnmatch(f, exclude), class_files)
|
||||||
|
|
||||||
|
Jar(class_files, classes_dir, jar_path)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = optparse.OptionParser()
|
parser = optparse.OptionParser()
|
||||||
parser.add_option('--classes-dir', help='Directory containing .class files.')
|
parser.add_option('--classes-dir', help='Directory containing .class files.')
|
||||||
|
@ -48,7 +52,9 @@ def main():
|
||||||
|
|
||||||
options, _ = parser.parse_args()
|
options, _ = parser.parse_args()
|
||||||
|
|
||||||
DoJar(options)
|
JarDirectory(options.classes_dir,
|
||||||
|
build_utils.ParseGypList(options.excluded_classes),
|
||||||
|
options.jar_path)
|
||||||
|
|
||||||
if options.stamp:
|
if options.stamp:
|
||||||
build_utils.Touch(options.stamp)
|
build_utils.Touch(options.stamp)
|
||||||
|
|
|
@ -7,12 +7,15 @@
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from util import build_utils
|
from util import build_utils
|
||||||
from util import md5_check
|
from util import md5_check
|
||||||
|
|
||||||
|
import jar
|
||||||
|
|
||||||
sys.path.append(build_utils.COLORAMA_ROOT)
|
sys.path.append(build_utils.COLORAMA_ROOT)
|
||||||
import colorama
|
import colorama
|
||||||
|
|
||||||
|
@ -49,14 +52,10 @@ def ColorJavacOutput(output):
|
||||||
|
|
||||||
return '\n'.join(map(ApplyColor, output.split('\n')))
|
return '\n'.join(map(ApplyColor, output.split('\n')))
|
||||||
|
|
||||||
|
def DoJavac(
|
||||||
def DoJavac(options, args):
|
classpath, javac_includes, classes_dir, chromium_code, java_files):
|
||||||
output_dir = options.output_dir
|
if javac_includes:
|
||||||
|
javac_includes = build_utils.ParseGypList(javac_includes)
|
||||||
src_gendirs = build_utils.ParseGypList(options.src_gendirs)
|
|
||||||
java_files = args + build_utils.FindInDirectories(src_gendirs, '*.java')
|
|
||||||
if options.javac_includes:
|
|
||||||
javac_includes = build_utils.ParseGypList(options.javac_includes)
|
|
||||||
filtered_java_files = []
|
filtered_java_files = []
|
||||||
for f in java_files:
|
for f in java_files:
|
||||||
for include in javac_includes:
|
for include in javac_includes:
|
||||||
|
@ -69,7 +68,7 @@ def DoJavac(options, args):
|
||||||
# crash... Sorted order works, so use that.
|
# crash... Sorted order works, so use that.
|
||||||
# See https://code.google.com/p/guava-libraries/issues/detail?id=950
|
# See https://code.google.com/p/guava-libraries/issues/detail?id=950
|
||||||
java_files.sort()
|
java_files.sort()
|
||||||
classpath = build_utils.ParseGypList(options.classpath)
|
classpath = build_utils.ParseGypList(classpath)
|
||||||
|
|
||||||
jar_inputs = []
|
jar_inputs = []
|
||||||
for path in classpath:
|
for path in classpath:
|
||||||
|
@ -83,8 +82,8 @@ def DoJavac(options, args):
|
||||||
'-source', '1.5',
|
'-source', '1.5',
|
||||||
'-target', '1.5',
|
'-target', '1.5',
|
||||||
'-classpath', ':'.join(classpath),
|
'-classpath', ':'.join(classpath),
|
||||||
'-d', output_dir]
|
'-d', classes_dir]
|
||||||
if options.chromium_code:
|
if chromium_code:
|
||||||
javac_args.extend(['-Xlint:unchecked', '-Xlint:deprecation'])
|
javac_args.extend(['-Xlint:unchecked', '-Xlint:deprecation'])
|
||||||
else:
|
else:
|
||||||
# XDignore.symbol.file makes javac compile against rt.jar instead of
|
# XDignore.symbol.file makes javac compile against rt.jar instead of
|
||||||
|
@ -95,19 +94,12 @@ def DoJavac(options, args):
|
||||||
javac_cmd = ['javac'] + javac_args + java_files
|
javac_cmd = ['javac'] + javac_args + java_files
|
||||||
|
|
||||||
def Compile():
|
def Compile():
|
||||||
# Delete the classes directory. This ensures that all .class files in the
|
|
||||||
# output are actually from the input .java files. For example, if a .java
|
|
||||||
# file is deleted or an inner class is removed, the classes directory should
|
|
||||||
# not contain the corresponding old .class file after running this action.
|
|
||||||
build_utils.DeleteDirectory(output_dir)
|
|
||||||
build_utils.MakeDirectory(output_dir)
|
|
||||||
build_utils.CheckOutput(
|
build_utils.CheckOutput(
|
||||||
javac_cmd,
|
javac_cmd,
|
||||||
print_stdout=options.chromium_code,
|
print_stdout=chromium_code,
|
||||||
stderr_filter=ColorJavacOutput)
|
stderr_filter=ColorJavacOutput)
|
||||||
|
|
||||||
|
record_path = os.path.join(classes_dir, 'javac.md5.stamp')
|
||||||
record_path = '%s/javac.md5.stamp' % options.output_dir
|
|
||||||
md5_check.CallAndRecordIfStale(
|
md5_check.CallAndRecordIfStale(
|
||||||
Compile,
|
Compile,
|
||||||
record_path=record_path,
|
record_path=record_path,
|
||||||
|
@ -119,21 +111,59 @@ def main():
|
||||||
colorama.init()
|
colorama.init()
|
||||||
|
|
||||||
parser = optparse.OptionParser()
|
parser = optparse.OptionParser()
|
||||||
parser.add_option('--src-gendirs',
|
parser.add_option(
|
||||||
|
'--src-gendirs',
|
||||||
help='Directories containing generated java files.')
|
help='Directories containing generated java files.')
|
||||||
parser.add_option('--javac-includes',
|
|
||||||
help='A list of file patterns. If provided, only java files that match' +
|
|
||||||
'one of the patterns will be compiled.')
|
|
||||||
parser.add_option('--classpath', help='Classpath for javac.')
|
parser.add_option('--classpath', help='Classpath for javac.')
|
||||||
parser.add_option('--output-dir', help='Directory for javac output.')
|
parser.add_option(
|
||||||
|
'--javac-includes',
|
||||||
|
help='A list of file patterns. If provided, only java files that match' +
|
||||||
|
'one of the patterns will be compiled.')
|
||||||
|
parser.add_option(
|
||||||
|
'--jar-excluded-classes',
|
||||||
|
help='List of .class file patterns to exclude from the jar.')
|
||||||
|
|
||||||
|
parser.add_option(
|
||||||
|
'--chromium-code',
|
||||||
|
type='int',
|
||||||
|
help='Whether code being compiled should be built with stricter '
|
||||||
|
'warnings for chromium code.')
|
||||||
|
|
||||||
|
parser.add_option(
|
||||||
|
'--classes-dir',
|
||||||
|
help='Directory for compiled .class files.')
|
||||||
|
parser.add_option('--jar-path', help='Jar output path.')
|
||||||
|
|
||||||
parser.add_option('--stamp', help='Path to touch on success.')
|
parser.add_option('--stamp', help='Path to touch on success.')
|
||||||
parser.add_option('--chromium-code', type='int', help='Whether code being '
|
|
||||||
'compiled should be built with stricter warnings for '
|
|
||||||
'chromium code.')
|
|
||||||
|
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
DoJavac(options, args)
|
java_files = args
|
||||||
|
if options.src_gendirs:
|
||||||
|
src_gendirs = build_utils.ParseGypList(options.src_gendirs)
|
||||||
|
java_files += build_utils.FindInDirectories(src_gendirs, '*.java')
|
||||||
|
|
||||||
|
with build_utils.TempDir() as classes_dir:
|
||||||
|
DoJavac(
|
||||||
|
options.classpath,
|
||||||
|
options.javac_includes,
|
||||||
|
classes_dir,
|
||||||
|
options.chromium_code,
|
||||||
|
java_files)
|
||||||
|
|
||||||
|
if options.jar_path:
|
||||||
|
jar.JarDirectory(classes_dir,
|
||||||
|
build_utils.ParseGypList(options.jar_excluded_classes),
|
||||||
|
options.jar_path)
|
||||||
|
|
||||||
|
if options.classes_dir:
|
||||||
|
# Delete the old classes directory. This ensures that all .class files in
|
||||||
|
# the output are actually from the input .java files. For example, if a
|
||||||
|
# .java file is deleted or an inner class is removed, the classes
|
||||||
|
# directory should not contain the corresponding old .class file after
|
||||||
|
# running this action.
|
||||||
|
build_utils.DeleteDirectory(options.classes_dir)
|
||||||
|
shutil.copytree(classes_dir, options.classes_dir)
|
||||||
|
|
||||||
if options.stamp:
|
if options.stamp:
|
||||||
build_utils.Touch(options.stamp)
|
build_utils.Touch(options.stamp)
|
||||||
|
|
|
@ -41,7 +41,10 @@ def DeleteDirectory(dir_path):
|
||||||
shutil.rmtree(dir_path)
|
shutil.rmtree(dir_path)
|
||||||
|
|
||||||
|
|
||||||
def Touch(path):
|
def Touch(path, fail_if_missing=False):
|
||||||
|
if fail_if_missing and not os.path.exists(path):
|
||||||
|
raise Exception(path + ' doesn\'t exist.')
|
||||||
|
|
||||||
MakeDirectory(os.path.dirname(path))
|
MakeDirectory(os.path.dirname(path))
|
||||||
with open(path, 'a'):
|
with open(path, 'a'):
|
||||||
os.utime(path, None)
|
os.utime(path, None)
|
||||||
|
|
24
java.gypi
24
java.gypi
|
@ -230,14 +230,17 @@
|
||||||
],
|
],
|
||||||
'outputs': [
|
'outputs': [
|
||||||
'<(compile_stamp)',
|
'<(compile_stamp)',
|
||||||
|
'<(javac_jar_path)',
|
||||||
],
|
],
|
||||||
'action': [
|
'action': [
|
||||||
'python', '<(DEPTH)/build/android/gyp/javac.py',
|
'python', '<(DEPTH)/build/android/gyp/javac.py',
|
||||||
'--output-dir=<(classes_dir)',
|
'--classes-dir=<(classes_dir)',
|
||||||
'--classpath=>(input_jars_paths)',
|
'--classpath=>(input_jars_paths)',
|
||||||
'--src-gendirs=>(generated_src_dirs)',
|
'--src-gendirs=>(generated_src_dirs)',
|
||||||
'--javac-includes=<(javac_includes)',
|
'--javac-includes=<(javac_includes)',
|
||||||
'--chromium-code=<(chromium_code)',
|
'--chromium-code=<(chromium_code)',
|
||||||
|
'--jar-path=<(javac_jar_path)',
|
||||||
|
'--jar-excluded-classes=<(jar_excluded_classes)',
|
||||||
'--stamp=<(compile_stamp)',
|
'--stamp=<(compile_stamp)',
|
||||||
'>@(java_sources)',
|
'>@(java_sources)',
|
||||||
]
|
]
|
||||||
|
@ -260,25 +263,6 @@
|
||||||
],
|
],
|
||||||
'includes': [ 'android/lint_action.gypi' ],
|
'includes': [ 'android/lint_action.gypi' ],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'action_name': 'jar_<(_target_name)',
|
|
||||||
'message': 'Creating <(_target_name) jar',
|
|
||||||
'inputs': [
|
|
||||||
'<(DEPTH)/build/android/gyp/util/build_utils.py',
|
|
||||||
'<(DEPTH)/build/android/gyp/util/md5_check.py',
|
|
||||||
'<(DEPTH)/build/android/gyp/jar.py',
|
|
||||||
'<(compile_stamp)',
|
|
||||||
],
|
|
||||||
'outputs': [
|
|
||||||
'<(javac_jar_path)',
|
|
||||||
],
|
|
||||||
'action': [
|
|
||||||
'python', '<(DEPTH)/build/android/gyp/jar.py',
|
|
||||||
'--classes-dir=<(classes_dir)',
|
|
||||||
'--jar-path=<(javac_jar_path)',
|
|
||||||
'--excluded-classes=<(jar_excluded_classes)',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'action_name': 'instr_jar_<(_target_name)',
|
'action_name': 'instr_jar_<(_target_name)',
|
||||||
'message': 'Instrumenting <(_target_name) jar',
|
'message': 'Instrumenting <(_target_name) jar',
|
||||||
|
|
|
@ -94,10 +94,10 @@
|
||||||
'jar_stamp': '<(intermediate_dir)/jar.stamp',
|
'jar_stamp': '<(intermediate_dir)/jar.stamp',
|
||||||
'obfuscate_stamp': '<(intermediate_dir)/obfuscate.stamp',
|
'obfuscate_stamp': '<(intermediate_dir)/obfuscate.stamp',
|
||||||
'strip_stamp': '<(intermediate_dir)/strip.stamp',
|
'strip_stamp': '<(intermediate_dir)/strip.stamp',
|
||||||
'classes_dir': '<(intermediate_dir)/classes',
|
'classes_dir': '<(intermediate_dir)/classes/2',
|
||||||
'classes_final_dir': '<(intermediate_dir)/classes_instr',
|
|
||||||
'javac_includes': [],
|
'javac_includes': [],
|
||||||
'jar_excluded_classes': [],
|
'jar_excluded_classes': [],
|
||||||
|
'javac_jar_path': '<(intermediate_dir)/<(_target_name).javac.jar',
|
||||||
'jar_path': '<(PRODUCT_DIR)/lib.java/<(jar_name)',
|
'jar_path': '<(PRODUCT_DIR)/lib.java/<(jar_name)',
|
||||||
'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar',
|
'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar',
|
||||||
'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar',
|
'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar',
|
||||||
|
@ -153,7 +153,6 @@
|
||||||
'apk_package_native_libs_dir': '<(apk_package_native_libs_dir)',
|
'apk_package_native_libs_dir': '<(apk_package_native_libs_dir)',
|
||||||
'unsigned_standalone_apk_path': '<(unsigned_standalone_apk_path)',
|
'unsigned_standalone_apk_path': '<(unsigned_standalone_apk_path)',
|
||||||
'extra_native_libs': [],
|
'extra_native_libs': [],
|
||||||
'apk_dex_input_paths': [ '>@(library_dexed_jars_paths)' ],
|
|
||||||
},
|
},
|
||||||
# Pass the jar path to the apk's "fake" jar target. This would be better as
|
# Pass the jar path to the apk's "fake" jar target. This would be better as
|
||||||
# direct_dependent_settings, but a variable set by a direct_dependent_settings
|
# direct_dependent_settings, but a variable set by a direct_dependent_settings
|
||||||
|
@ -540,14 +539,17 @@
|
||||||
],
|
],
|
||||||
'outputs': [
|
'outputs': [
|
||||||
'<(compile_stamp)',
|
'<(compile_stamp)',
|
||||||
|
'<(javac_jar_path)',
|
||||||
],
|
],
|
||||||
'action': [
|
'action': [
|
||||||
'python', '<(DEPTH)/build/android/gyp/javac.py',
|
'python', '<(DEPTH)/build/android/gyp/javac.py',
|
||||||
'--output-dir=<(classes_dir)',
|
'--classes-dir=<(classes_dir)',
|
||||||
'--classpath=>(input_jars_paths) <(android_sdk_jar)',
|
'--classpath=>(input_jars_paths) <(android_sdk_jar)',
|
||||||
'--src-gendirs=>(gen_src_dirs)',
|
'--src-gendirs=>(gen_src_dirs)',
|
||||||
'--javac-includes=<(javac_includes)',
|
'--javac-includes=<(javac_includes)',
|
||||||
'--chromium-code=<(chromium_code)',
|
'--chromium-code=<(chromium_code)',
|
||||||
|
'--jar-path=<(javac_jar_path)',
|
||||||
|
'--jar-excluded-classes=<(jar_excluded_classes)',
|
||||||
'--stamp=<(compile_stamp)',
|
'--stamp=<(compile_stamp)',
|
||||||
'>@(java_sources)',
|
'>@(java_sources)',
|
||||||
],
|
],
|
||||||
|
@ -571,42 +573,22 @@
|
||||||
'includes': [ 'android/lint_action.gypi' ],
|
'includes': [ 'android/lint_action.gypi' ],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'action_name': 'instr_classes_<(_target_name)',
|
'action_name': 'instr_jar_<(_target_name)',
|
||||||
'message': 'Instrumenting <(_target_name) classes',
|
'message': 'Instrumenting <(_target_name) jar',
|
||||||
'variables': {
|
'variables': {
|
||||||
'input_path': '<(classes_dir)',
|
'input_path': '<(javac_jar_path)',
|
||||||
'output_path': '<(classes_final_dir)',
|
'output_path': '<(jar_path)',
|
||||||
'stamp_path': '<(instr_stamp)',
|
'stamp_path': '<(instr_stamp)',
|
||||||
'instr_type': 'classes',
|
'instr_type': 'jar',
|
||||||
},
|
},
|
||||||
'inputs': [
|
|
||||||
'<(compile_stamp)',
|
|
||||||
],
|
|
||||||
'outputs': [
|
'outputs': [
|
||||||
'<(instr_stamp)',
|
'<(instr_stamp)',
|
||||||
],
|
|
||||||
'includes': [ 'android/instr_action.gypi' ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'action_name': 'jar_<(_target_name)',
|
|
||||||
'message': 'Creating <(_target_name) jar',
|
|
||||||
'inputs': [
|
|
||||||
'<(DEPTH)/build/android/gyp/util/build_utils.py',
|
|
||||||
'<(DEPTH)/build/android/gyp/util/md5_check.py',
|
|
||||||
'<(DEPTH)/build/android/gyp/jar.py',
|
|
||||||
'<(instr_stamp)',
|
|
||||||
],
|
|
||||||
'outputs': [
|
|
||||||
'<(jar_stamp)',
|
|
||||||
'<(jar_path)',
|
'<(jar_path)',
|
||||||
],
|
],
|
||||||
'action': [
|
'inputs': [
|
||||||
'python', '<(DEPTH)/build/android/gyp/jar.py',
|
'<(javac_jar_path)',
|
||||||
'--classes-dir=<(classes_final_dir)',
|
],
|
||||||
'--jar-path=<(jar_path)',
|
'includes': [ 'android/instr_action.gypi' ],
|
||||||
'--excluded-classes=<(jar_excluded_classes)',
|
|
||||||
'--stamp=<(jar_stamp)',
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'action_name': 'obfuscate_<(_target_name)',
|
'action_name': 'obfuscate_<(_target_name)',
|
||||||
|
@ -696,11 +678,11 @@
|
||||||
{
|
{
|
||||||
'action_name': 'dex_<(_target_name)',
|
'action_name': 'dex_<(_target_name)',
|
||||||
'variables': {
|
'variables': {
|
||||||
'output_path': '<(dex_path)',
|
|
||||||
'dex_input_paths': [
|
'dex_input_paths': [
|
||||||
'>@(apk_dex_input_paths)',
|
'>@(library_dexed_jars_paths)',
|
||||||
'<(jar_path)',
|
'<(jar_path)',
|
||||||
],
|
],
|
||||||
|
'output_path': '<(dex_path)',
|
||||||
'proguard_enabled_input_path': '<(obfuscated_jar_path)',
|
'proguard_enabled_input_path': '<(obfuscated_jar_path)',
|
||||||
},
|
},
|
||||||
'target_conditions': [
|
'target_conditions': [
|
||||||
|
|
Загрузка…
Ссылка в новой задаче