linkCppImplStubs function

void linkCppImplStubs(
  1. List<ModuleInfo> moduleInfos, {
  2. String baseDir = '.',
})

Builds the #if guard condition that determines on which platforms the auto-register call should fire inside a src/HybridXxx.cpp stub. For each NativeImpl.cpp module that targets Android, Linux, iOS, or macOS, creates a starter src/Hybrid${Module}.cpp stub if one doesn't already exist.

Always created for Android/Linux/iOS/macOS-C++ modules — this is the shared, single-file default every plugin starts from, kept regardless of whether Windows and/or Linux later diverge into their own windows/src/ / linux/src/ file (see hasCustomPlatformImpl — separation is opt-in per platform by actually writing code in that file, not automatic just because a module targets NativeImpl.cpp on both desktop platforms). A plugin that never diverges keeps this ONE file as its only impl, on purpose — sharing genuinely-identical logic across platforms is often the better choice, not a fallback.

Implementation

void linkCppImplStubs(List<ModuleInfo> moduleInfos, {String baseDir = '.'}) {
  // Ensure src/ exists before writing stubs (createSync is idempotent).
  Directory(p.join(baseDir, 'src')).createSync(recursive: true);

  // Only create stubs for modules whose src/ file is actually compiled:
  // android/linux (isNativeCpp), iOS (iosIsCpp), or macOS (macosIsCpp).
  // Windows-only modules use windows/src/ instead (see linkWindowsCppImplStubs).
  for (final m in moduleInfos.where(
    (m) => m.isNativeCpp || m.iosIsCpp || m.macosIsCpp,
  )) {
    final className = _toPascalCase(m.lib);
    final stubFile = File(p.join(baseDir, 'src', 'Hybrid$className.cpp'));
    if (stubFile.existsSync()) {
      // Never overwrite user code — but keep the generated auto-register
      // guard in step with the spec: a platform switched to C++ after the
      // stub was written would otherwise never register its impl.
      _refreshAutoRegisterGuard(stubFile, m);
      continue;
    }
    var stub = t.cppImplStubContent(
      lib: m.lib,
      className: className,
      isNativeCpp: m.isNativeCpp,
      isAndroidCpp: m.isAndroidCpp,
      iosIsCpp: m.iosIsCpp,
      macosIsCpp: m.macosIsCpp,
      windowsIsCpp: m.windowsIsCpp,
      webIsWasm: m.webIsWasm,
    );
    // The template's class is empty (abstract — does not compile); take the
    // generator's full starter (every override, throwing) when it exists.
    final starter = File(p.join(baseDir, 'lib', 'src', 'generated', 'cpp', '${m.lib}.impl.g.cpp'));
    final cls = starter.existsSync() ? RegExp(r'^class \w+Impl final : public Hybrid\w+ \{[\s\S]*?^\};', multiLine: true).firstMatch(starter.readAsStringSync()) : null;
    if (cls != null) {
      final body = cls.group(0)!.replaceAll(RegExp('\\b${className}Impl\\b'), 'Hybrid${className}Impl');
      stub = stub
          .replaceFirst(RegExp(r'^class Hybrid\w+Impl final[\s\S]*?^\};', multiLine: true), body)
          .replaceFirst('#include <string>\n', '#include <stdexcept>\n#include <string>\n');
    }
    stubFile.writeAsStringSync(stub);
  }
}