Pass Linux build mode on command line (#41551)

Currently Linux builds override the default BUILD mode by putting it in
the generated config. That makes it sticky for manual runs of make,
which is inconsistent with how other platforms work.

Instead, pass the build mode as a command-line override, the same way
someone would if building directly with make. This makes the flow of
controlling the mode less confusing.

Fixes #41528
This commit is contained in:
stuartmorgan 2019-09-30 09:36:40 -07:00 committed by GitHub
parent 67ea92cbca
commit d1761f1072
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 31 deletions

View File

@ -17,11 +17,9 @@ import '../reporting/reporting.dart';
/// Builds the Linux project through the Makefile.
Future<void> buildLinux(LinuxProject linuxProject, BuildInfo buildInfo, {String target = 'lib/main.dart'}) async {
final String buildFlag = buildInfo?.isDebug == true ? 'debug' : 'release';
final StringBuffer buffer = StringBuffer('''
# Generated code do not commit.
export FLUTTER_ROOT=${Cache.flutterRoot}
export BUILD=$buildFlag
export TRACK_WIDGET_CREATION=${buildInfo?.trackWidgetCreation == true}
export FLUTTER_TARGET=$target
export PROJECT_DIR=${linuxProject.project.directory.path}
@ -48,12 +46,14 @@ export PROJECT_DIR=${linuxProject.project.directory.path}
}
// Invoke make.
final String buildFlag = getNameForBuildMode(buildInfo.mode ?? BuildMode.release);
final Stopwatch sw = Stopwatch()..start();
final Process process = await processManager.start(<String>[
'make',
'-C',
linuxProject.makeFile.parent.path,
], runInShell: true);
'BUILD=$buildFlag'
]);
final Status status = logger.startProgress(
'Building Linux application...',
timeout: null,

View File

@ -54,6 +54,26 @@ void main() {
when(notLinuxPlatform.isWindows).thenReturn(false);
});
// Creates the mock files necessary to run a build.
void setUpMockProjectFilesForBuild() {
fs.file('linux/build.sh').createSync(recursive: true);
fs.file('pubspec.yaml').createSync();
fs.file('.packages').createSync();
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
}
// Sets up mock expectation for running 'make'.
void expectMakeInvocationWithMode(String buildModeName) {
when(mockProcessManager.start(<String>[
'make',
'-C',
'/linux',
'BUILD=$buildModeName',
])).thenAnswer((Invocation invocation) async {
return mockProcess;
});
}
testUsingContext('Linux build fails when there is no linux project', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
@ -69,10 +89,7 @@ void main() {
testUsingContext('Linux build fails on non-linux platform', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
fs.file('linux/build.sh').createSync(recursive: true);
fs.file('pubspec.yaml').createSync();
fs.file('.packages').createSync();
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
setUpMockProjectFilesForBuild();
expect(createTestCommandRunner(command).run(
const <String>['build', 'linux']
@ -86,18 +103,8 @@ void main() {
testUsingContext('Linux build invokes make and writes temporary files', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
fs.file('linux/build.sh').createSync(recursive: true);
fs.file('pubspec.yaml').createSync();
fs.file('.packages').createSync();
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
when(mockProcessManager.start(<String>[
'make',
'-C',
'/linux',
], runInShell: true)).thenAnswer((Invocation invocation) async {
return mockProcess;
});
setUpMockProjectFilesForBuild();
expectMakeInvocationWithMode('release');
await createTestCommandRunner(command).run(
const <String>['build', 'linux']
@ -110,6 +117,38 @@ void main() {
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
testUsingContext('Linux build --debug passes debug mode to make', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
expectMakeInvocationWithMode('debug');
await createTestCommandRunner(command).run(
const <String>['build', 'linux', '--debug']
);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(),
ProcessManager: () => mockProcessManager,
Platform: () => linuxPlatform,
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
testUsingContext('Linux build --profile passes profile mode to make', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
expectMakeInvocationWithMode('profile');
await createTestCommandRunner(command).run(
const <String>['build', 'linux', '--profile']
);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(),
ProcessManager: () => mockProcessManager,
Platform: () => linuxPlatform,
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
testUsingContext('linux can extract binary name from Makefile', () async {
fs.file('linux/Makefile')
..createSync(recursive: true)
@ -140,18 +179,8 @@ BINARY_NAME=fizz_bar
testUsingContext('Release build prints an under-construction warning', () async {
final BuildCommand command = BuildCommand();
applyMocksToCommand(command);
fs.file('linux/build.sh').createSync(recursive: true);
fs.file('pubspec.yaml').createSync();
fs.file('.packages').createSync();
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
when(mockProcessManager.start(<String>[
'make',
'-C',
'/linux',
], runInShell: true)).thenAnswer((Invocation invocation) async {
return mockProcess;
});
setUpMockProjectFilesForBuild();
expectMakeInvocationWithMode('release');
await createTestCommandRunner(command).run(
const <String>['build', 'linux']