Future _createKernel()

in build_modules/lib/src/kernel_builder.dart [138:230]


Future<void> _createKernel(
    {required Module module,
    required BuildStep buildStep,
    required bool summaryOnly,
    required String outputExtension,
    required String targetName,
    required String dartSdkDir,
    required String sdkKernelPath,
    required String librariesPath,
    required bool useIncrementalCompiler,
    required bool trackUnusedInputs,
    required Iterable<String> experiments,
    required bool soundNullSafety}) async {
  var request = WorkRequest();
  var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
  var outputId = module.primarySource.changeExtension(outputExtension);
  var outputFile = scratchSpace.fileFor(outputId);
  var kernelDeps = <AssetId>[];

  // Maps the inputs paths we provide to the kernel worker to asset ids,
  // if `trackUnusedInputs` is `true`.
  Map<String, AssetId>? kernelInputPathToId;
  // If `trackUnusedInputs` is `true`, this is the file we will use to
  // communicate the used inputs with the kernel worker.
  File? usedInputsFile;

  await buildStep.trackStage('CollectDeps', () async {
    var sourceDeps = <AssetId>[];

    await _findModuleDeps(
        module, kernelDeps, sourceDeps, buildStep, outputExtension);

    var allAssetIds = <AssetId>{
      ...module.sources,
      ...kernelDeps,
      ...sourceDeps,
    };
    await scratchSpace.ensureAssets(allAssetIds, buildStep);

    if (trackUnusedInputs) {
      usedInputsFile = await File(p.join(
              (await Directory.systemTemp.createTemp('kernel_builder_')).path,
              'used_inputs.txt'))
          .create();
      kernelInputPathToId = {};
    }

    await _addRequestArguments(
        request,
        module,
        kernelDeps,
        targetName,
        dartSdkDir,
        sdkKernelPath,
        librariesPath,
        outputFile,
        summaryOnly,
        useIncrementalCompiler,
        buildStep,
        experiments,
        soundNullSafety,
        usedInputsFile: usedInputsFile,
        kernelInputPathToId: kernelInputPathToId);
  });

  // We need to make sure and clean up the temp dir, even if we fail to compile.
  try {
    var frontendWorker = await buildStep.fetchResource(frontendDriverResource);
    var response = await frontendWorker.doWork(request,
        trackWork: (response) => buildStep
            .trackStage('Kernel Generate', () => response, isExternal: true));
    if (response.exitCode != EXIT_CODE_OK || !await outputFile.exists()) {
      throw KernelException(
          outputId, '${request.arguments.join(' ')}\n${response.output}');
    }

    if (response.output.isNotEmpty) {
      log.info(response.output);
    }

    // Copy the output back using the buildStep.
    await scratchSpace.copyOutput(outputId, buildStep, requireContent: true);

    // Note that we only want to do this on success, we can't trust the unused
    // inputs if there is a failure.
    if (usedInputsFile != null) {
      await reportUnusedKernelInputs(
          usedInputsFile!, kernelDeps, kernelInputPathToId!, buildStep);
    }
  } finally {
    await usedInputsFile?.parent.delete(recursive: true);
  }
}