buildHookDart function
String
buildHookDart({
- required List<
NativeAssetsModule> modules, - String vendoredDir = 'src/nitro_native',
Contents of hook/build.dart — one CBuilder.library per modules entry
(multi-module plugins build one code asset each; each module's generated
Dart resolves against its own asset). The vendored Dart DL API in
vendoredDir is compiled into every asset.
Implementation
String buildHookDart({
required List<NativeAssetsModule> modules,
String vendoredDir = 'src/nitro_native',
}) {
String builder(NativeAssetsModule m) {
final sources = [
...m.cppSources,
for (final c in nativeAssetsVendoredCSources) '$vendoredDir/$c',
].map((s) => " '$s',").join('\n');
return ''' await CBuilder.library(
name: '${m.libStem}',
assetName: '${m.libStem}',
language: Language.cpp,
sources: [
$sources
],
// vendored nitro C runtime + the generated-cpp dir (the impl #includes
// <lib>.native.g.h, which lives beside the generated bridge).
includes: ['$vendoredDir', 'lib/src/generated/cpp'],
std: 'c++17',
cppLinkStdLib: android ? 'c++_static' : null,
).run(input: input, output: output, logger: logger);''';
}
final builders = modules.map(builder).join('\n');
return '''
// GENERATED BY nitrogen — native-assets build hook (do not edit).
import 'dart:io';
import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
import 'package:native_toolchain_c/native_toolchain_c.dart';
// Compiles each Nitro C++ bridge + impl (+ vendored Dart DL API) into its own
// code asset. CBuilder cross-compiles for whichever target the SDK/Flutter
// requests (xcrun / NDK / clang / cl); the generated `@Native` bindings resolve
// against these assets.
void main(List<String> args) async {
await build(args, (input, output) async {
// Android's NDK defaults to the SHARED libc++ (libc++_shared.so), which a
// bare code asset doesn't bundle → dlopen fails. Link it statically so the
// .so is self-contained. Apple/Linux keep their system default.
final android = input.config.code.targetOS == OS.android;
// Root logger ('') — setting .level on a NAMED logger throws unless
// hierarchicalLoggingEnabled is set, so use the root here.
final logger = Logger('')
..level = Level.SEVERE
..onRecord.listen((r) => stderr.writeln('\${r.level.name}: \${r.message}'));
$builders
});
}
''';
}