Commit 9c6ffc82 authored by Jakob Andersen's avatar Jakob Andersen Committed by GitHub

Use snapshot's .d file as source inputs in Gradle build. (#8756)

* Use snapshot's .d file as source inputs in Gradle build.

If we don't yet have a .d file (first build), fall back to using the
.dart files in the current directory. This enables us to detect changes
in dependent source files (Flutter framework, packages outside the
source directory, etc.), and re-generate the snapshots as needed.

Unfortunately, Gradle requires knowing the source files before executing
the task, and can't update them after building, so Gradle considers the
second build to be out-of-date (because it has more input files than the
first build). Sub-sequent builds have the correct dependency
information, and will be skipped if the source files haven't changed.

Also added a dependency on gen_snapshot. The snapshot ABI isn't stable,
so we need to re-generate the snapshots when we roll the Dart SDK
dependency.

Fixes #8315
Fixes #8687
Fixes #8607
parent 616a7bed
......@@ -207,9 +207,45 @@ class FlutterTask extends DefaultTask {
}
}
FileCollection readDependencies(File dependenciesFile) {
if (dependenciesFile.exists()) {
try {
// Dependencies file has Makefile syntax:
// <target> <files>: <source> <files> <separated> <by> <space>
String depText = dependenciesFile.text
return project.files(depText.split(': ')[1].split())
} catch (Exception e) {
logger.error("Error reading dependency file ${dependenciesFile}: ${e}")
}
}
return null
}
@InputFiles
FileCollection getSourceFiles() {
return project.fileTree(dir: sourceDir, exclude: ['android', 'ios'], include: ['**/*.dart', 'pubspec.yaml', 'flutter.yaml'])
File dependenciesFile
if (buildMode != 'debug') {
dependenciesFile = project.file("${intermediateDir}/snapshot.d")
} else {
dependenciesFile = project.file("${intermediateDir}/snapshot_blob.bin.d")
}
FileCollection sources = readDependencies(dependenciesFile)
if (sources != null) {
// We have a dependencies file. Add a dependency on gen_snapshot as well, since the
// snapshots have to be rebuilt if it changes.
FileCollection snapshotter = readDependencies(project.file("${intermediateDir}/gen_snapshot.d"))
if (snapshotter != null) {
sources = sources.plus(snapshotter)
}
// Finally, add a dependency on pubspec.yaml as well.
return sources.plus(project.files('pubspec.yaml'))
}
// No dependencies file (or problems parsing it). Fall back to source files.
return project.fileTree(
dir: sourceDir,
exclude: ['android', 'ios'],
include: ['**/*.dart', 'pubspec.yaml']
)
}
@TaskAction
......
......@@ -124,6 +124,7 @@ Future<String> _buildAotSnapshot(
final String vmSnapshotInstructions = fs.path.join(outputDir.path, 'vm_snapshot_instr');
final String isolateSnapshotData = fs.path.join(outputDir.path, 'isolate_snapshot_data');
final String isolateSnapshotInstructions = fs.path.join(outputDir.path, 'isolate_snapshot_instr');
final String dependencies = fs.path.join(outputDir.path, 'snapshot.d');
final String vmEntryPoints = artifacts.getArtifactPath(Artifact.dartVmEntryPointsTxt, platform, buildMode);
final String ioEntryPoints = artifacts.getArtifactPath(Artifact.dartIoEntriesTxt, platform, buildMode);
......@@ -198,6 +199,7 @@ Future<String> _buildAotSnapshot(
'--url_mapping=dart:jni,$jniPath',
'--url_mapping=dart:vmservice_sky,$vmServicePath',
'--print_snapshot_sizes',
'--dependencies=$dependencies',
];
if (!interpreter) {
......@@ -249,6 +251,10 @@ Future<String> _buildAotSnapshot(
return null;
}
// Write path to gen_snapshot, since snapshots have to be re-generated when we roll
// the Dart SDK.
await outputDir.childFile('gen_snapshot.d').writeAsString('snapshot.d: $genSnapshot\n');
// On iOS, we use Xcode to compile the snapshot into a dynamic library that the
// end-developer can link into their app.
if (platform == TargetPlatform.ios) {
......
......@@ -50,6 +50,7 @@ Future<int> createSnapshot({
];
if (depfilePath != null) {
args.add('--dependencies=$depfilePath');
fs.file(depfilePath).parent.childFile('gen_snapshot.d').writeAsString('$depfilePath: $snapshotterPath\n');
}
args.add(mainPath);
return runCommandAndStreamOutput(args);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment