cmake_custom_command_migration.dart 2.85 KB
Newer Older
1 2 3 4 5 6
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import '../base/file_system.dart';
import '../base/project_migrator.dart';
7
import '../cmake_project.dart';
8 9 10 11 12

// CMake's add_custom_command() should use VERBATIM to handle escaping of spaces
// and special characters correctly.
// See https://github.com/flutter/flutter/issues/67270.
class CmakeCustomCommandMigration extends ProjectMigrator {
13 14
  CmakeCustomCommandMigration(CmakeBasedProject project, super.logger)
    : _cmakeFile = project.managedCmakeFile;
15 16 17 18

  final File _cmakeFile;

  @override
19
  void migrate() {
20 21
    if (!_cmakeFile.existsSync()) {
      logger.printTrace('CMake project not found, skipping add_custom_command() VERBATIM migration');
22
      return;
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    }

    final String originalProjectContents = _cmakeFile.readAsStringSync();
    // Example:
    //
    // add_custom_command(
    //   OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
    //     ${CMAKE_CURRENT_BINARY_DIR}/_phony_
    //   COMMAND ${CMAKE_COMMAND} -E env
    //     ${FLUTTER_TOOL_ENVIRONMENT}
    //     "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
    //       linux-x64 ${CMAKE_BUILD_TYPE}
    // )

    // Match the whole add_custom_command() and append VERBATIM unless it
    // already exists.
    final RegExp addCustomCommand = RegExp(
      r'add_custom_command\(\s*(.*?)\s*\)',
      multiLine: true,
      dotAll: true,
    );

    String newProjectContents = originalProjectContents;

    final Iterable<RegExpMatch> matches = addCustomCommand.allMatches(originalProjectContents);

    for (final RegExpMatch match in matches) {
50 51
      final String? addCustomCommandOriginal = match.group(1);
      if (addCustomCommandOriginal != null && addCustomCommandOriginal.contains('VERBATIM') == false) {
52 53 54
        final String addCustomCommandReplacement = '$addCustomCommandOriginal\n  VERBATIM';
        newProjectContents = newProjectContents.replaceAll(addCustomCommandOriginal, addCustomCommandReplacement);
      }
55 56 57 58 59 60 61 62

      // CMake's add_custom_command() should add FLUTTER_TARGET_PLATFORM to support multi-architecture.
      // However, developers would get the following warning every time if we do nothing.
      // ------------------------------
      // CMake Warning:
      //   Manually-specified variables were not used by the project:
      //    FLUTTER_TARGET_PLATFORM
      // ------------------------------
63
      if (addCustomCommandOriginal?.contains('linux-x64') ?? false) {
64 65
        newProjectContents = newProjectContents.replaceAll('linux-x64', r'${FLUTTER_TARGET_PLATFORM}');
      }
66 67
    }
    if (originalProjectContents != newProjectContents) {
68
      logger.printStatus('add_custom_command() missing VERBATIM or FLUTTER_TARGET_PLATFORM, updating.');
69
      _cmakeFile.writeAsStringSync(newProjectContents);
70 71 72
    }
  }
}