generateCMakeContent function

String generateCMakeContent(
  1. String pluginName,
  2. List<String> moduleLibs,
  3. String nitroNativePath, {
  4. List<({bool isAndroidCpp, bool isNativeCpp, String lib, String module})>? moduleInfos,
  5. String? linkChecksum,
})

Generates the full content of a fresh src/CMakeLists.txt.

pluginName is the main plugin library name. moduleLibs are additional module library names. nitroNativePath is kept for API compatibility; the generated file uses the local src/native copy populated by nitrogen link. moduleInfos drives per-module C++ decisions.

Implementation

String generateCMakeContent(
  String pluginName,
  List<String> moduleLibs,
  String nitroNativePath, {
  List<({String lib, String module, bool isNativeCpp, bool isAndroidCpp})>? moduleInfos,
  String? linkChecksum,
}) {
  final mainInfo = moduleInfos?.firstWhere(
    (m) => m.lib == pluginName,
    orElse: () => (lib: pluginName, module: pluginName, isNativeCpp: false, isAndroidCpp: false),
  );
  final mainClassName = _toPascalCase(mainInfo?.module ?? pluginName);
  // Impl file is always added via a separate target_sources call below (not
  // inlined into add_library's file list) so a Windows/Linux caller can
  // override which file to compile via NITRO_IMPL_SRC — see
  // _implSourcesBlock and needsSeparateWindowsImpl/needsSeparateLinuxImpl
  // on ModuleInfo. Android C++: unguarded. Linux-only C++: guard with
  // if(NOT ANDROID) so Android Kotlin builds skip it.
  final mainImplSources = mainInfo?.isNativeCpp == true ? _implSourcesBlock(pluginName, mainClassName, unguarded: mainInfo?.isAndroidCpp == true) : '';

  final buf = StringBuffer()
    ..writeln('cmake_minimum_required(VERSION ${BuildVersions.cmakeMinimum})')
    ..writeln('project(${pluginName}_library VERSION 0.0.1 LANGUAGES C CXX)')
    ..writeln()
    ..writeln('set(CMAKE_CXX_STANDARD ${BuildVersions.cmakeCxxStandard})')
    ..writeln('set(CMAKE_CXX_STANDARD_REQUIRED ON)')
    ..writeln()
    ..writeln('set(NITRO_NATIVE "$localNitroNativeCmakePath")')
    ..writeln(_linkChecksumStamp(linkChecksum))
    ..writeln()
    ..writeln('add_library($pluginName SHARED')
    ..writeln('  "$pluginName.cpp"')
    ..writeln('  "\${CMAKE_CURRENT_SOURCE_DIR}/../lib/src/generated/cpp/$pluginName.bridge.g.cpp"')
    ..writeln('  "dart_api_dl.c"')
    ..writeln(')')
    ..write(mainImplSources)
    ..writeln('target_include_directories($pluginName PRIVATE')
    ..writeln('  "\${CMAKE_CURRENT_SOURCE_DIR}"')
    ..writeln('  "\${CMAKE_CURRENT_SOURCE_DIR}/../lib/src/generated/cpp"')
    ..writeln('  "\${NITRO_NATIVE}"')
    ..writeln(')')
    ..writeln('target_compile_definitions($pluginName PUBLIC DART_SHARED_LIB)')
    ..writeln('if(ANDROID)')
    ..writeln('  target_link_libraries($pluginName PRIVATE android log)')
    ..writeln('  target_link_options($pluginName PRIVATE "-Wl,-z,max-page-size=16384")')
    ..writeln('elseif(WIN32)')
    ..writeln('  target_link_libraries($pluginName PRIVATE dbghelp)')
    ..writeln('elseif(UNIX AND NOT APPLE)')
    ..writeln('  target_link_libraries($pluginName PRIVATE dl pthread)')
    ..writeln('endif()');

  for (final lib in moduleLibs) {
    if (lib == pluginName) continue;
    final info = moduleInfos?.firstWhere(
      (m) => m.lib == lib,
      orElse: () => (lib: lib, module: lib, isNativeCpp: false, isAndroidCpp: false),
    );
    buf.write(
      cmakeModuleTarget(
        lib,
        isCpp: info?.isNativeCpp ?? false,
        isAndroidCpp: info?.isAndroidCpp ?? false,
      ),
    );
  }
  return buf.toString();
}