From d1761f1072973f0f01989868ed4dea762684d68c Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 30 Sep 2019 09:36:40 -0700 Subject: [PATCH] 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 --- .../lib/src/linux/build_linux.dart | 6 +- .../commands/build_linux_test.dart | 85 +++++++++++++------ 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/packages/flutter_tools/lib/src/linux/build_linux.dart b/packages/flutter_tools/lib/src/linux/build_linux.dart index 2c6a5ef61c..b3fc6b12fb 100644 --- a/packages/flutter_tools/lib/src/linux/build_linux.dart +++ b/packages/flutter_tools/lib/src/linux/build_linux.dart @@ -17,11 +17,9 @@ import '../reporting/reporting.dart'; /// Builds the Linux project through the Makefile. Future 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([ 'make', '-C', linuxProject.makeFile.parent.path, - ], runInShell: true); + 'BUILD=$buildFlag' + ]); final Status status = logger.startProgress( 'Building Linux application...', timeout: null, diff --git a/packages/flutter_tools/test/general.shard/commands/build_linux_test.dart b/packages/flutter_tools/test/general.shard/commands/build_linux_test.dart index 5dd6ec70ed..eda702d878 100644 --- a/packages/flutter_tools/test/general.shard/commands/build_linux_test.dart +++ b/packages/flutter_tools/test/general.shard/commands/build_linux_test.dart @@ -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([ + '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 ['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([ - 'make', - '-C', - '/linux', - ], runInShell: true)).thenAnswer((Invocation invocation) async { - return mockProcess; - }); + setUpMockProjectFilesForBuild(); + expectMakeInvocationWithMode('release'); await createTestCommandRunner(command).run( const ['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 ['build', 'linux', '--debug'] + ); + }, overrides: { + 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 ['build', 'linux', '--profile'] + ); + }, overrides: { + 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([ - 'make', - '-C', - '/linux', - ], runInShell: true)).thenAnswer((Invocation invocation) async { - return mockProcess; - }); + setUpMockProjectFilesForBuild(); + expectMakeInvocationWithMode('release'); await createTestCommandRunner(command).run( const ['build', 'linux']