run method
Future<void>
run({
- required BuildInput input,
- required BuildOutputBuilder output,
- required Logger? logger,
Run the native build pipeline.
This is the main entry point that replaces PrebuiltCodeAssetBuilder.run.
Implementation
Future<void> run({
required BuildInput input,
required BuildOutputBuilder output,
required Logger? logger,
}) async {
final code = input.config.code;
if (!input.config.buildCodeAssets) {
_logInfo(
logger,
'Skipping native_prebuilt: buildCodeAssets is disabled.',
);
return;
}
final target = targetFromCodeConfig(code);
final configuredLinkMode = project.asset.linkMode;
final requestedLinkMode = _requestedLinkMode(
code.linkModePreference,
configuredLinkMode,
);
final manifestPayload = project.prebuilts.artifacts[target.label]?.payload;
final payload = _payloadForRequest(
requestedLinkMode: requestedLinkMode,
manifestPayload: manifestPayload,
);
final linkMode = _linkModeForPayload(payload, requestedLinkMode);
_logInfo(
logger,
'Resolving ${project.asset.libraryStem} for ${target.label} '
'(${payload is DynamicLibraryPayload ? 'dynamic' : 'static'}).',
);
// Try prebuilt resolution first
if (project.prebuiltPolicy == PrebuiltPolicy.preferPrebuilt &&
_manifestSupportsPayload(manifestPayload, payload)) {
final context = PrebuiltResolutionContext(
input: input,
manifest: project.prebuilts,
target: target,
libraryStem: project.asset.libraryStem,
payload: payload,
localSearchRoot: Directory.fromUri(input.outputDirectory),
logger: logger,
);
final chain =
resolvers ??
[
UserDefinePrebuiltResolver(),
LocalPrebuiltResolver(directoryName: localDirectoryName),
SharedCacheResolver(),
];
ResolvedPrebuilt? result;
for (final resolver in chain) {
_logInfo(logger, 'Trying ${resolver.runtimeType}...');
result = await resolver.resolve(context);
if (result != null) break;
}
if (result is ResolvedPrebuiltFound) {
final libraryName = canonicalLibraryName(
target: target,
libraryStem: project.asset.libraryStem,
payload: payload,
);
final bundledLibUri = input.outputDirectory.resolve(libraryName);
await File(result.file.path).copy(File.fromUri(bundledLibUri).path);
output.assets.code.add(
CodeAsset(
package: input.packageName,
name: project.asset.assetName,
linkMode: linkMode,
file: bundledLibUri,
),
);
_logInfo(
logger,
'Using prebuilt ${project.asset.libraryStem} for ${target.label} '
'(from ${result.source.label})',
);
return;
}
}
// Fall back to source build
_logInfo(
logger,
'No prebuilt available for ${target.label}; attempting source build.',
);
// Check if we have a recipe for this target
final recipe = project.build.recipeFor(target);
if (recipe != null) {
// Use the new recipe-based build system via executor
await _buildWithExecutor(
target: target,
linkMode: linkMode,
payload: payload,
input: input,
output: output,
logger: logger,
);
return;
}
// Fall back to source builder callback if available
if (sourceFallback != null) {
await _buildWithSourceFallback(
target: target,
linkMode: linkMode,
payload: payload,
input: input,
output: output,
logger: logger,
);
return;
}
final message =
'No build recipe or source fallback for ${project.asset.libraryStem} '
'on ${target.label}.';
_logWarning(logger, message);
throw StateError(message);
}