createSharedHeaders function
void
createSharedHeaders(
Implementation
void createSharedHeaders(String nitroNativePath, {String baseDir = '.'}) {
Directory(p.join(baseDir, 'src')).createSync(recursive: true);
final localNativeDir = Directory(p.join(baseDir, 'src', 'native'));
localNativeDir.createSync(recursive: true);
Directory(p.join(localNativeDir.path, 'internal')).createSync(recursive: true);
final srcFile = File(p.join(nitroNativePath, 'nitro.h'));
// If the source nitro.h is missing the required macros, update it first.
if (srcFile.existsSync()) {
final current = srcFile.readAsStringSync();
if (!current.contains('NITRO_EXPORT')) {
srcFile.writeAsStringSync(nitroHContent);
}
} else {
// If it doesn't exist in the nitro package at all, create it.
try {
srcFile.createSync(recursive: true);
srcFile.writeAsStringSync(nitroHContent);
} catch (_) {
// Might not have write access to the installed package; that's fine,
// we'll write to the local project.
}
}
// Always write the correct content to the local project directories.
File(p.join(baseDir, 'src', 'nitro.h')).writeAsStringSync(nitroHContent);
File(p.join(localNativeDir.path, 'nitro.h')).writeAsStringSync(nitroHContent);
for (final headerName in ['dart_api_dl.h', 'dart_api.h', 'dart_native_api.h', 'dart_version.h', 'nitro_wasm_compat.h']) {
final src = File(p.join(nitroNativePath, headerName));
if (src.existsSync()) src.copySync(p.join(localNativeDir.path, headerName));
}
final implHeader = File(p.join(nitroNativePath, 'internal', 'dart_api_dl_impl.h'));
if (implHeader.existsSync()) {
implHeader.copySync(p.join(localNativeDir.path, 'internal', 'dart_api_dl_impl.h'));
}
if (Directory(p.join(baseDir, 'ios', 'Classes')).existsSync()) {
File(
p.join(baseDir, 'ios', 'Classes', 'nitro.h'),
).writeAsStringSync(nitroHContent);
}
if (Directory(p.join(baseDir, 'macos', 'Classes')).existsSync()) {
File(
p.join(baseDir, 'macos', 'Classes', 'nitro.h'),
).writeAsStringSync(nitroHContent);
}
File(
p.join(baseDir, 'src', 'dart_api_dl.c'),
).writeAsStringSync(bundledDartApiDlContent);
// Also populate any existing SPM C++ target include/ dirs (nested layout:
// {platform}/<pluginName>/Sources/<ClassName>Cpp/include/).
for (final platform in ['ios', 'macos']) {
final platformDir = Directory(p.join(baseDir, platform));
if (!platformDir.existsSync()) continue;
for (final entry in platformDir.listSync().whereType<Directory>()) {
final sourcesDir = Directory(p.join(entry.path, 'Sources'));
if (!sourcesDir.existsSync()) continue;
final packageSwift = File(p.join(entry.path, 'Package.swift'));
final packageSwiftContent = packageSwift.existsSync() ? packageSwift.readAsStringSync() : '';
final pluginClass = _toPascalCase(p.basename(entry.path));
for (final targetDir in sourcesDir.listSync().whereType<Directory>()) {
final targetName = p.basename(targetDir.path);
if (!targetName.endsWith('Cpp')) continue;
// A per-module target that depends on the plugin-level `<Class>Cpp`
// target resolves these headers through it, and link/apple.dart deletes
// any copies there — planting them here flipped the same five files on
// every generate/link pair. Same predicate as the deletion.
final moduleClass = targetName.substring(0, targetName.length - 3);
if (targetName != '${pluginClass}Cpp' && _spmModuleDependsOnPluginCpp(packageSwiftContent, moduleClass, pluginClass)) continue;
final includeDir = Directory(p.join(targetDir.path, 'include'));
if (!includeDir.existsSync()) continue;
// Write nitro.h with the correct guard-protected content.
File(p.join(includeDir.path, 'nitro.h')).writeAsStringSync(nitroHContent);
// Copy dart API headers from the nitro native source. NOT
// nitro_wasm_compat.h: SwiftPM compiles every header in include/, and
// that one #errors outside Emscripten. link/apple.dart deletes stale
// copies; copying it here re-planted it on every generate.
for (final headerName in ['dart_api_dl.h', 'dart_api.h', 'dart_native_api.h', 'dart_version.h']) {
final src = File(p.join(nitroNativePath, headerName));
if (src.existsSync()) src.copySync(p.join(includeDir.path, headerName));
}
}
}
}
}