build_aar.dart 5.38 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import '../android/android_builder.dart';
6
import '../android/gradle_utils.dart';
7
import '../base/common.dart';
8 9

import '../base/file_system.dart';
10 11
import '../base/os.dart';
import '../build_info.dart';
12
import '../cache.dart';
13
import '../globals.dart' as globals;
14
import '../project.dart';
15
import '../reporting/reporting.dart';
16
import '../runner/flutter_command.dart' show FlutterCommandResult;
17 18 19
import 'build.dart';

class BuildAarCommand extends BuildSubCommand {
20
  BuildAarCommand({ required bool verboseHelp }) : super(verboseHelp: verboseHelp) {
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
    argParser
      ..addFlag(
        'debug',
        defaultsTo: true,
        help: 'Build a debug version of the current project.',
      )
      ..addFlag(
        'profile',
        defaultsTo: true,
        help: 'Build a version of the current project specialized for performance profiling.',
      )
      ..addFlag(
        'release',
        defaultsTo: true,
        help: 'Build a release version of the current project.',
      );
37
    addTreeShakeIconsFlag();
38
    usesFlavorOption();
39
    usesBuildNumberOption();
40
    usesPubOption();
41 42
    addSplitDebugInfoOption();
    addDartObfuscationOption();
43
    usesDartDefineOption();
44
    usesExtraDartFlagOptions(verboseHelp: verboseHelp);
45
    usesTrackWidgetCreation(verboseHelp: false);
46 47
    addNullSafetyModeOptions(hide: !verboseHelp);
    addEnableExperimentation(hide: !verboseHelp);
48
    addAndroidSpecificBuildOptions(hide: !verboseHelp);
49
    argParser
50 51
      ..addMultiOption(
        'target-platform',
52
        defaultsTo: <String>['android-arm', 'android-arm64', 'android-x64'],
53 54 55
        allowed: <String>['android-arm', 'android-arm64', 'android-x86', 'android-x64'],
        help: 'The target platform for which the project is compiled.',
      )
56 57
      ..addOption(
        'output-dir',
58
        help: 'The absolute path to the directory where the repository is generated. '
59
              'By default, this is "<current-directory>android/build".',
60 61 62 63 64 65
      );
  }

  @override
  final String name = 'aar';

66 67 68
  @override
  bool get reportNullSafety => false;

69 70 71 72 73
  @override
  Future<Set<DevelopmentArtifact>> get requiredArtifacts async => <DevelopmentArtifact>{
    DevelopmentArtifact.androidGenSnapshot,
  };

74
  @override
75
  Future<CustomDimensions> get usageValues async {
xster's avatar
xster committed
76 77
    final FlutterProject flutterProject = _getProject();
    if (flutterProject == null) {
78
      return const CustomDimensions();
79
    }
80 81

    String projectType;
xster's avatar
xster committed
82
    if (flutterProject.manifest.isModule) {
83
      projectType = 'module';
xster's avatar
xster committed
84
    } else if (flutterProject.manifest.isPlugin) {
85
      projectType = 'plugin';
86
    } else {
87
      projectType = 'app';
88
    }
89 90 91 92 93

    return CustomDimensions(
      commandBuildAarProjectType: projectType,
      commandBuildAarTargetPlatform: stringsArg('target-platform').join(','),
    );
94 95 96 97
  }

  @override
  final String description = 'Build a repository containing an AAR and a POM file.\n\n'
98 99
      'By default, AARs are built for `release`, `debug` and `profile`.\n'
      'The POM file is used to include the dependencies that the AAR was compiled against.\n'
100
      'To learn more about how to use these artifacts, see '
101 102 103
      'https://flutter.dev/go/build-aar\n'
      'Note: this command builds applications assuming that the entrypoint is lib/main.dart. '
      'This cannot currently be configured.';
104 105 106

  @override
  Future<FlutterCommandResult> runCommand() async {
107
    if (globals.androidSdk == null) {
108 109
      exitWithNoSdkMessage();
    }
110
    final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{};
111 112 113 114

    final Iterable<AndroidArch> targetArchitectures =
        stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName);

115
    final String? buildNumberArg = stringArgDeprecated('build-number');
116
    final String buildNumber = argParser.options.containsKey('build-number')
117 118 119
      && buildNumberArg != null
      && buildNumberArg.isNotEmpty
      ? buildNumberArg
120
      : '1.0';
121

122
    final File targetFile = globals.fs.file(globals.fs.path.join('lib', 'main.dart'));
123
    for (final String buildMode in const <String>['debug', 'profile', 'release']) {
124
      if (boolArgDeprecated(buildMode)) {
125 126
        androidBuildInfo.add(
          AndroidBuildInfo(
127 128 129 130
            await getBuildInfo(
              forcedBuildMode: BuildMode.fromName(buildMode),
              forcedTargetFile: targetFile,
            ),
131 132 133
            targetArchs: targetArchitectures,
          )
        );
134 135 136 137 138
      }
    }
    if (androidBuildInfo.isEmpty) {
      throwToolExit('Please specify a build mode and try again.');
    }
139

140
    displayNullSafetyMode(androidBuildInfo.first.buildInfo);
141
    await androidBuilder?.buildAar(
142
      project: _getProject(),
143
      target: targetFile.path,
144
      androidBuildInfo: androidBuildInfo,
145
      outputDirectoryPath: stringArgDeprecated('output-dir'),
146
      buildNumber: buildNumber,
147
    );
148
    return FlutterCommandResult.success();
149 150
  }

151
  /// Returns the [FlutterProject] which is determined from the remaining command-line
152 153
  /// argument if any or the current working directory.
  FlutterProject _getProject() {
154 155
    final List<String> remainingArguments = argResults!.rest;
    if (remainingArguments.isEmpty) {
156 157
      return FlutterProject.current();
    }
158
    return FlutterProject.fromDirectory(globals.fs.directory(findProjectRoot(globals.fs, remainingArguments.first)));
159 160
  }
}