Unverified Commit 4d05ed5d authored by Dan Field's avatar Dan Field Committed by GitHub

Local engine build mode (#52043)

parent 24883e1c
...@@ -209,9 +209,20 @@ List<String> _xcodeBuildSettingsLines({ ...@@ -209,9 +209,20 @@ List<String> _xcodeBuildSettingsLines({
if (globals.artifacts is LocalEngineArtifacts) { if (globals.artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = globals.artifacts as LocalEngineArtifacts; final LocalEngineArtifacts localEngineArtifacts = globals.artifacts as LocalEngineArtifacts;
final String engineOutPath = localEngineArtifacts.engineOutPath; final String engineOutPath = globals.fs.path.basename(localEngineArtifacts.engineOutPath);
String engineBuildMode = 'release';
if (engineOutPath.toLowerCase().contains('debug')) {
engineBuildMode = 'debug';
} else if (engineOutPath.toLowerCase().contains('profile')) {
engineBuildMode = 'profile';
}
xcodeBuildSettings.add('FLUTTER_ENGINE=${globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath))}'); xcodeBuildSettings.add('FLUTTER_ENGINE=${globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath))}');
xcodeBuildSettings.add('LOCAL_ENGINE=${globals.fs.path.basename(engineOutPath)}'); xcodeBuildSettings.add('LOCAL_ENGINE=$engineOutPath');
// Only write this for local engines, where it is supposed to be sticky to
// match the engine configuration. Avoid writing it otherwise so that it
// does not stick the user with the wrong build mode, particularly for
// existing app use cases.
xcodeBuildSettings.add('FLUTTER_BUILD_MODE=$engineBuildMode');
// Tell Xcode not to build universal binaries for local engines, which are // Tell Xcode not to build universal binaries for local engines, which are
// single-architecture. // single-architecture.
......
...@@ -433,22 +433,24 @@ Information about project "Runner": ...@@ -433,22 +433,24 @@ Information about project "Runner":
}); });
group('updateGeneratedXcodeProperties', () { group('updateGeneratedXcodeProperties', () {
MockLocalEngineArtifacts mockArtifacts; MockLocalEngineArtifacts mockEngineArtifacts;
MockArtifacts mockArtifacts;
MockProcessManager mockProcessManager; MockProcessManager mockProcessManager;
FakePlatform macOS; FakePlatform macOS;
FileSystem fs; FileSystem fs;
setUp(() { setUp(() {
fs = MemoryFileSystem(); fs = MemoryFileSystem();
mockArtifacts = MockLocalEngineArtifacts(); mockEngineArtifacts = MockLocalEngineArtifacts();
mockArtifacts = MockArtifacts();
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
macOS = fakePlatform('macos'); macOS = fakePlatform('macos');
fs.file(xcodebuild).createSync(recursive: true); fs.file(xcodebuild).createSync(recursive: true);
}); });
void testUsingOsxContext(String description, dynamic testMethod()) { void testUsingOsxContext(String description, dynamic testMethod(), {bool isLocalEngine = true}) {
testUsingContext(description, testMethod, overrides: <Type, Generator>{ testUsingContext(description, testMethod, overrides: <Type, Generator>{
Artifacts: () => mockArtifacts, Artifacts: () => isLocalEngine ? mockEngineArtifacts : mockArtifacts,
Platform: () => macOS, Platform: () => macOS,
FileSystem: () => fs, FileSystem: () => fs,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
...@@ -456,9 +458,9 @@ Information about project "Runner": ...@@ -456,9 +458,9 @@ Information about project "Runner":
} }
testUsingOsxContext('sets OTHER_LDFLAGS for iOS', () async { testUsingOsxContext('sets OTHER_LDFLAGS for iOS', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn(fs.path.join('engine', 'Flutter.framework')); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn(fs.path.join('engine', 'Flutter.framework'));
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
...@@ -481,9 +483,9 @@ Information about project "Runner": ...@@ -481,9 +483,9 @@ Information about project "Runner":
}); });
testUsingOsxContext('do not set OTHER_LDFLAGS for macOS', () async { testUsingOsxContext('do not set OTHER_LDFLAGS for macOS', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterMacOSFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterMacOSFramework,
platform: TargetPlatform.darwin_x64, mode: anyNamed('mode'))).thenReturn(fs.path.join('engine', 'FlutterMacOS.framework')); platform: TargetPlatform.darwin_x64, mode: anyNamed('mode'))).thenReturn(fs.path.join('engine', 'FlutterMacOS.framework'));
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
...@@ -507,9 +509,9 @@ Information about project "Runner": ...@@ -507,9 +509,9 @@ Information about project "Runner":
}); });
testUsingOsxContext('sets ARCHS=armv7 when armv7 local engine is set', () async { testUsingOsxContext('sets ARCHS=armv7 when armv7 local engine is set', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine'); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
...@@ -531,10 +533,59 @@ Information about project "Runner": ...@@ -531,10 +533,59 @@ Information about project "Runner":
expect(buildPhaseScriptContents.contains('ARCHS=armv7'), isTrue); expect(buildPhaseScriptContents.contains('ARCHS=armv7'), isTrue);
}); });
testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async { testUsingOsxContext('sets FLUTTER_BUILD_MODE local engine is set', () async {
when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.profile, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
project: project,
buildInfo: buildInfo,
);
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
expect(config.existsSync(), isTrue);
final String contents = config.readAsStringSync();
expect(contents, contains('FLUTTER_BUILD_MODE=profile'));
final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
expect(buildPhaseScript.existsSync(), isTrue);
final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
expect(buildPhaseScriptContents, contains('FLUTTER_BUILD_MODE=profile'));
});
testUsingOsxContext('does not set FLUTTER_BUILD_MODE without local engine', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine'); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.profile, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
project: project,
buildInfo: buildInfo,
);
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
expect(config.existsSync(), isTrue);
final String contents = config.readAsStringSync();
expect(contents, isNot(contains('FLUTTER_BUILD_MODE=')));
final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
expect(buildPhaseScript.existsSync(), isTrue);
final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
expect(buildPhaseScriptContents, isNot(contains('FLUTTER_BUILD_MODE=')));
}, isLocalEngine: false);
testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async {
when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties( await updateGeneratedXcodeProperties(
...@@ -556,9 +607,9 @@ Information about project "Runner": ...@@ -556,9 +607,9 @@ Information about project "Runner":
}); });
testUsingOsxContext('does not set TRACK_WIDGET_CREATION when trackWidgetCreation is false', () async { testUsingOsxContext('does not set TRACK_WIDGET_CREATION when trackWidgetCreation is false', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine'); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties( await updateGeneratedXcodeProperties(
...@@ -580,9 +631,9 @@ Information about project "Runner": ...@@ -580,9 +631,9 @@ Information about project "Runner":
}); });
testUsingOsxContext('sets ARCHS=armv7 when armv7 local engine is set', () async { testUsingOsxContext('sets ARCHS=armv7 when armv7 local engine is set', () async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine'); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false); const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
final FlutterProject project = FlutterProject.fromPath('path/to/project'); final FlutterProject project = FlutterProject.fromPath('path/to/project');
...@@ -613,9 +664,9 @@ Information about project "Runner": ...@@ -613,9 +664,9 @@ Information about project "Runner":
String expectedBuildName, String expectedBuildName,
String expectedBuildNumber, String expectedBuildNumber,
}) async { }) async {
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework, when(mockEngineArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine'); platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios')); when(mockEngineArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios'));
final File manifestFile = fs.file('path/to/project/pubspec.yaml'); final File manifestFile = fs.file('path/to/project/pubspec.yaml');
manifestFile.createSync(recursive: true); manifestFile.createSync(recursive: true);
...@@ -809,3 +860,4 @@ class MockAnsiTerminal extends Mock implements AnsiTerminal { ...@@ -809,3 +860,4 @@ class MockAnsiTerminal extends Mock implements AnsiTerminal {
@override @override
bool get supportsColor => false; bool get supportsColor => false;
} }
class MockArtifacts extends Mock implements Artifacts {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment