linkCppImplStubs function
For each NativeImpl.cpp module that targets Android or Linux, creates a
starter src/Hybrid${Module}.cpp stub if one doesn't already exist.
Only android/linux modules need this in src/ — Windows-only cpp modules
use windows/CMakeLists.txt and their stub belongs in windows/src/.
The check uses ModuleInfo.isNativeCpp (narrow: android|linux) rather than
ModuleInfo.isCpp (broad: any platform) to avoid creating a
HybridBenchmark.cpp stub for a module that is only C++ on Windows.
Implementation
void linkCppImplStubs(List<ModuleInfo> moduleInfos, {String baseDir = '.'}) {
for (final m in moduleInfos.where((m) => m.isNativeCpp)) {
final className = _toPascalCase(m.lib);
final stubFile = File(p.join(baseDir, 'src', 'Hybrid$className.cpp'));
if (stubFile.existsSync()) continue; // never overwrite user code
stubFile.writeAsStringSync(
'// Hybrid$className — NativeImpl.cpp implementation.\n'
'// Generated by nitrogen link. Fill in the method bodies.\n'
'#include "../lib/src/generated/cpp/${m.lib}.native.g.h"\n'
'\n'
'#include <string>\n'
'\n'
'class Hybrid${className}Impl final : public Hybrid$className {\n'
'public:\n'
' // TODO: implement all pure-virtual methods declared in Hybrid$className\n'
'};\n'
'\n'
'static Hybrid${className}Impl g_impl;\n'
'\n'
'// Auto-register on shared library load — no manual init call needed.\n'
'#if defined(_WIN32)\n'
'// MSVC lacks __attribute__((constructor)); use a static object instead.\n'
'namespace {\n'
' struct _AutoRegister {\n'
' _AutoRegister() { ${m.lib}_register_impl(&g_impl); }\n'
' };\n'
' _AutoRegister _auto_register_instance;\n'
'}\n'
'#else\n'
'__attribute__((constructor))\n'
'static void ${m.lib}_auto_register() {\n'
' ${m.lib}_register_impl(&g_impl);\n'
'}\n'
'#endif\n',
);
}
}