run method

  1. @override
Future<void> run({
  1. required BuildInput input,
  2. required BuildOutputBuilder output,
  3. required Logger? logger,
  4. List<AssetRouting> routing = const [ToAppBundle()],
})

Runs the C Compiler with on this C build spec.

Completes with an error if the build fails.

Implementation

@override
Future<void> run({
  required BuildInput input,
  required BuildOutputBuilder output,
  required Logger? logger,
  List<AssetRouting> routing = const [ToAppBundle()],
}) async {
  if (!input.config.buildCodeAssets) {
    logger?.info(
      'config.buildAssetTypes did not contain CodeAssets, '
      'skipping CodeAsset $assetName build.',
    );
    return;
  }
  assert(
    input.config.linkingEnabled || routing.whereType<ToLinkHook>().isEmpty,
    'ToLinker can only be provided if input.config.linkingEnabled'
    ' is true.',
  );
  final outDir = input.outputDirectory;
  final packageRoot = input.packageRoot;
  await Directory.fromUri(outDir).create(recursive: true);
  final linkMode = getLinkMode(
    linkModePreference ?? input.config.code.linkModePreference,
  );
  final libUri = outDir.resolve(
    input.config.code.targetOS.libraryFileName(name, linkMode),
  );
  final exeUri = outDir.resolve(
    input.config.code.targetOS.executableFileName(name),
  );
  final sources = [
    for (final source in this.sources)
      packageRoot.resolveUri(Uri.file(source)),
  ];
  final includes = [
    for (final directory in this.includes)
      packageRoot.resolveUri(Uri.file(directory)),
  ];
  final forcedIncludes = [
    for (final file in this.forcedIncludes)
      packageRoot.resolveUri(Uri.file(file)),
  ];
  final dartBuildFiles = [
    // ignore: deprecated_member_use_from_same_package
    for (final source in this.dartBuildFiles) packageRoot.resolve(source),
  ];
  final libraryDirectories = [
    for (final directory in this.libraryDirectories)
      outDir.resolveUri(Uri.file(directory)),
  ];

  final task = RunCBuilder(
    input: input,
    codeConfig: input.config.code,
    logger: logger,
    sources: sources,
    includes: includes,
    forcedIncludes: forcedIncludes,
    frameworks: frameworks,
    libraries: libraries,
    libraryDirectories: libraryDirectories,
    dynamicLibrary:
        type == OutputType.library && linkMode == DynamicLoadingBundled()
        ? libUri
        : null,
    staticLibrary: type == OutputType.library && linkMode == StaticLinking()
        ? libUri
        : null,
    executable: type == OutputType.executable ? exeUri : null,
    // ignore: invalid_use_of_visible_for_testing_member
    installName: installName,
    flags: flags,
    defines: {
      ...defines,
      if (buildModeDefine) buildMode.name.toUpperCase(): null,
      if (ndebugDefine && buildMode != BuildMode.debug) 'NDEBUG': null,
    },
    pic: pic,
    std: std,
    language: language,
    cppLinkStdLib: cppLinkStdLib,
    optimizationLevel: optimizationLevel,
  );
  await task.run();

  if (assetName != null) {
    for (final route in routing) {
      output.assets.code.add(
        CodeAsset(
          package: input.packageName,
          name: assetName!,
          file: libUri,
          linkMode: linkMode,
        ),
        routing: route,
      );
    }
  }

  final includeFiles = await Stream.fromIterable(includes)
      .asyncExpand(
        (include) => Directory(include.toFilePath())
            .list(recursive: true)
            .where((entry) => entry is File)
            .map((file) => file.uri),
      )
      .toList();

  output.addDependencies({
    // Note: We use a Set here to deduplicate the dependencies.
    ...sources,
    ...includeFiles,
    ...forcedIncludes,
    ...dartBuildFiles,
  });
}