build method

Future<BuildResult> build({
  1. required LinkModePreferenceImpl linkModePreference,
  2. required Target target,
  3. required Uri workingDirectory,
  4. required BuildModeImpl buildMode,
  5. CCompilerConfigImpl? cCompilerConfig,
  6. IOSSdkImpl? targetIOSSdk,
  7. int? targetAndroidNdkApi,
  8. required bool includeParentEnvironment,
  9. PackageLayout? packageLayout,
  10. String? runPackageName,
  11. Iterable<String>? supportedAssetTypes,
})

workingDirectory is expected to contain .dart_tool.

This method is invoked by launchers such as dartdev (for dart run) and flutter_tools (for flutter run and flutter build).

If provided, only native assets of all transitive dependencies of runPackageName are built.

Implementation

Future<BuildResult> build({
  required LinkModePreferenceImpl linkModePreference,
  required Target target,
  required Uri workingDirectory,
  required BuildModeImpl buildMode,
  CCompilerConfigImpl? cCompilerConfig,
  IOSSdkImpl? targetIOSSdk,
  int? targetAndroidNdkApi,
  required bool includeParentEnvironment,
  PackageLayout? packageLayout,
  String? runPackageName,
  Iterable<String>? supportedAssetTypes,
}) async {
  packageLayout ??= await PackageLayout.fromRootPackageRoot(workingDirectory);
  final packagesWithNativeAssets =
      await packageLayout.packagesWithNativeAssets;
  final List<Package> buildPlan;
  final PackageGraph packageGraph;
  if (packagesWithNativeAssets.length <= 1 && runPackageName == null) {
    buildPlan = packagesWithNativeAssets;
    packageGraph = PackageGraph({
      for (final p in packagesWithNativeAssets) p.name: [],
    });
  } else {
    final planner = await NativeAssetsBuildPlanner.fromRootPackageRoot(
      rootPackageRoot: packageLayout.rootPackageRoot,
      packagesWithNativeAssets: packagesWithNativeAssets,
      dartExecutable: Uri.file(Platform.resolvedExecutable),
      logger: logger,
    );
    final (plan, planSuccess) = planner.plan(
      runPackageName: runPackageName,
    );
    if (!planSuccess) {
      return _BuildResultImpl(
        assets: [],
        dependencies: [],
        success: false,
      );
    }
    buildPlan = plan;
    packageGraph = planner.packageGraph;
  }
  final assets = <AssetImpl>[];
  final dependencies = <Uri>[];
  final metadata = <String, Metadata>{};
  var success = true;
  for (final package in buildPlan) {
    final dependencyMetadata = _metadataForPackage(
      packageGraph: packageGraph,
      packageName: package.name,
      targetMetadata: metadata,
    );
    final config = await _cliConfig(
      packageName: package.name,
      packageRoot: packageLayout.packageRoot(package.name),
      target: target,
      buildMode: buildMode,
      linkMode: linkModePreference,
      buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
      dependencyMetadata: dependencyMetadata,
      cCompilerConfig: cCompilerConfig,
      targetIOSSdk: targetIOSSdk,
      targetAndroidNdkApi: targetAndroidNdkApi,
      supportedAssetTypes: supportedAssetTypes,
    );
    final (
      packageAssets,
      packageDependencies,
      packageMetadata,
      packageSuccess,
    ) = await _buildPackageCached(
      config,
      packageLayout.packageConfigUri,
      workingDirectory,
      includeParentEnvironment,
    );
    assets.addAll(packageAssets);
    dependencies.addAll(packageDependencies);
    success &= packageSuccess;
    if (packageMetadata != null) {
      metadata[config.packageName] = packageMetadata;
    }
  }
  return _BuildResultImpl(
    assets: assets,
    dependencies: dependencies..sort(_uriCompare),
    success: success,
  );
}