linkCMake function

void linkCMake(
  1. String pluginName,
  2. List<String> moduleLibs,
  3. String nitroNativePath, {
  4. String baseDir = '.',
  5. List<ModuleInfo>? moduleInfos,
})

Implementation

void linkCMake(
  String pluginName,
  List<String> moduleLibs,
  String nitroNativePath, {
  String baseDir = '.',
  List<ModuleInfo>? moduleInfos,
}) {
  createSharedHeaders(nitroNativePath, baseDir: baseDir);
  final cmakeFile = File(p.join(baseDir, 'src', 'CMakeLists.txt'));
  if (!cmakeFile.existsSync()) {
    generateCMake(
      pluginName,
      moduleLibs,
      nitroNativePath,
      baseDir: baseDir,
      moduleInfos: moduleInfos,
    );
    return;
  }
  var content = cmakeFile.readAsStringSync();
  bool modified = false;
  final stamp = _stampLinkSpecChecksum(content, computeLinkSpecChecksum(baseDir: baseDir));
  content = stamp.content;
  modified = modified || stamp.modified;

  final optGuard = _cmakeInsertOptimizationGuard(content);
  content = optGuard.content;
  modified = modified || optGuard.modified;
  const desiredNitroValue = _srcLocalNitroNativeCmakePath;
  final nitroNativeSetLine = 'set(NITRO_NATIVE "$desiredNitroValue")';
  if (!content.contains('NITRO_NATIVE')) {
    content = '$nitroNativeSetLine\n\n$content';
    modified = true;
  } else {
    final staleMatch = RegExp(
      r'set\(NITRO_NATIVE\s+"([^"]+)"\)',
    ).firstMatch(content);
    if (staleMatch != null && staleMatch.group(1) != desiredNitroValue) {
      content = content.replaceFirst(staleMatch.group(0)!, nitroNativeSetLine);
      modified = true;
    }
  }
  if (!content.contains('CMAKE_CXX_STANDARD')) {
    // Inject C++17 standard after the project() declaration.
    content = content.replaceFirstMapped(
      RegExp(r'project\([^)]+\)\s*\n'),
      (m) => '${m.group(0)!}\nset(CMAKE_CXX_STANDARD ${BuildVersions.cmakeCxxStandard})\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n',
    );
    modified = true;
  }
  if (!content.contains(r'${NITRO_NATIVE}')) {
    content = content.replaceFirst(
      'target_include_directories($pluginName PRIVATE',
      'target_include_directories($pluginName PRIVATE\n  "\${NITRO_NATIVE}"',
    );
    modified = true;
  }
  if (!content.contains('dart_api_dl.c')) {
    content = content.replaceFirst(
      'add_library($pluginName SHARED',
      'add_library($pluginName SHARED\n  "dart_api_dl.c"',
    );
    modified = true;
  }
  final bridgeRel = '../lib/src/generated/cpp/$pluginName.bridge.g.cpp';
  if (!content.contains(bridgeRel)) {
    content = content.replaceFirst(
      'add_library($pluginName SHARED',
      'add_library($pluginName SHARED\n  "\${CMAKE_CURRENT_SOURCE_DIR}/$bridgeRel"',
    );
    modified = true;
  }

  final mainImpl = _cmakeAddMainPluginImpl(
    content,
    moduleInfos,
    pluginName,
    baseDir,
  );
  content = mainImpl.content;
  modified = modified || mainImpl.modified;

  for (final lib in moduleLibs) {
    if (lib != pluginName && !content.contains('add_library($lib ')) {
      final info = moduleInfos?.firstWhere(
        (m) => m.lib == lib,
        orElse: () => ModuleInfo(lib: lib, module: lib, isCpp: false),
      );
      // Use isNativeCpp (android/linux) — only those platforms put
      // HybridXxx.cpp into src/CMakeLists.txt. Windows-only cpp uses
      // windows/CMakeLists.txt instead.
      content += ct.cmakeModuleTarget(
        lib,
        isCpp: info?.isNativeCpp ?? false,
        isAndroidCpp: info?.isAndroidCpp ?? false,
      );
      modified = true;
    }
  }

  final retrofit = _cmakeRetrofitImplSrcGuard(content, moduleInfos, baseDir);
  content = retrofit.content;
  modified = modified || retrofit.modified;
  if (modified) cmakeFile.writeAsStringSync(content);
}