Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
be2e7bb1
Unverified
Commit
be2e7bb1
authored
Nov 18, 2020
by
Dan Field
Committed by
GitHub
Nov 18, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Revert "Allow any iOS app to be added to an existing host app (#70647)" (#70739)" (#70740)
This reverts commit
aab9a76e
.
parent
aab9a76e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
440 additions
and
377 deletions
+440
-377
build_ios_framework_module_test.dart
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+390
-343
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+21
-6
plugins.dart
packages/flutter_tools/lib/src/plugins.dart
+11
-23
project.dart
packages/flutter_tools/lib/src/project.dart
+18
-5
No files found.
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
View file @
be2e7bb1
...
...
@@ -17,390 +17,437 @@ Future<void> main() async {
section
(
'Create module project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--template'
,
'module'
,
'hello'
],
);
});
section
(
'Add plugins'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info: 0.4.1
\n
package_info: 0.4.0+9
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
section
(
'Test module template'
);
// First, build the module in Debug to copy the debug version of Flutter.framework.
// This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
// otherwise building plugins with bitcode will fail linking because the debug version
// of Flutter.framework does not contain bitcode.
await
inDirectory
(
projectDir
,
()
async
{
final
Directory
moduleProjectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello_module'
));
await
flutter
(
'
build
'
,
'
create
'
,
options:
<
String
>[
'ios'
,
'--debug'
,
'--no-codesign'
,
'--org'
,
'io.flutter.devicelab'
,
'--template'
,
'module'
,
'hello_module'
],
);
});
// This builds all build modes' frameworks by default
section
(
'Build frameworks'
);
await
_testBuildIosFramework
(
moduleProjectDir
,
isModule:
true
);
const
String
outputDirectoryName
=
'flutter-frameworks'
;
section
(
'Test app template'
)
;
await
inDirectory
(
projectDir
,
()
async
{
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello_project'
));
await
flutter
(
'build'
,
options:
<
String
>[
'ios-framework'
,
'--universal'
,
'--output=
$outputDirectoryName
'
],
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'hello_project'
],
);
});
final
String
outputPath
=
path
.
join
(
projectDir
.
path
,
outputDirectoryName
);
section
(
'Check debug build has Dart snapshot as asset'
);
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
section
(
'Check debug build has no Dart AOT'
);
// There's still an App.framework with a dylib, but it's empty.
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
));
await
_testBuildIosFramework
(
projectDir
);
});
final
String
debugAppFrameworkPath
=
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
);
final
String
aotSymbols
=
await
dylibSymbols
(
debugAppFrameworkPath
);
if
(
aotSymbols
.
contains
(
'architecture'
)
||
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework contains AOT'
);
}
await
_checkFrameworkArchs
(
debugAppFrameworkPath
,
'Debug'
);
// Xcode changed the name of this generated directory in Xcode 12.
const
String
xcode11ArmDirectoryName
=
'ios-armv7_arm64'
;
const
String
xcode12ArmDirectoryName
=
'ios-arm64_armv7'
;
final
String
xcode11AppFrameworkDirectory
=
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
xcode11ArmDirectoryName
,
'App.framework'
,
'App'
,
);
final
String
xcode12AppFrameworkDirectory
=
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
xcode12ArmDirectoryName
,
'App.framework'
,
'App'
,
);
// This seemed easier than an explicit Xcode version check.
String
xcodeArmDirectoryName
;
if
(
exists
(
File
(
xcode11AppFrameworkDirectory
)))
{
xcodeArmDirectoryName
=
xcode11ArmDirectoryName
;
}
else
if
(
exists
(
File
(
xcode12AppFrameworkDirectory
)))
{
xcodeArmDirectoryName
=
xcode12ArmDirectoryName
;
}
else
{
throw
const
FileSystemException
(
'Expected App.framework binary to exist.'
);
}
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
section
(
'Check profile, release builds has Dart AOT dylib'
);
for
(
final
String
mode
in
<
String
>[
'Profile'
,
'Release'
])
{
final
String
appFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'App'
,
);
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
// rmTree(tempDir);
}
});
}
await
_checkFrameworkArchs
(
appFrameworkPath
,
mode
);
await
_checkBitcode
(
appFrameworkPath
,
mode
);
Future
<
void
>
_testBuildIosFramework
(
Directory
projectDir
,
{
bool
isModule
=
false
})
async
{
section
(
'Add plugins'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info: 0.4.1
\n
package_info: 0.4.0+9
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
final
String
aotSymbols
=
await
dylibSymbols
(
appFrameworkPath
);
// First, build the module in Debug to copy the debug version of Flutter.framework.
// This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
// otherwise building plugins with bitcode will fail linking because the debug version
// of Flutter.framework does not contain bitcode.
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios'
,
'--debug'
,
'--no-codesign'
,
],
);
});
if
(!
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework missing Dart AOT'
);
}
// This builds all build modes' frameworks by default
section
(
'Build frameworks'
);
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
const
String
outputDirectoryName
=
'flutter-frameworks'
;
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
xcodeArmDirectoryName
,
'App.framework'
,
'App'
,
));
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
}
section
(
"Check all modes' engine dylib"
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
engineFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Flutter'
,
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios-framework'
,
'--universal'
,
'--output=
$outputDirectoryName
'
],
);
});
await
_checkFrameworkArchs
(
engineFrameworkPath
,
mode
);
await
_checkBitcode
(
engineFrameworkPath
,
mode
);
final
String
outputPath
=
path
.
join
(
projectDir
.
path
,
outputDirectoryName
);
section
(
'Check debug build has Dart snapshot as asset'
);
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
section
(
'Check debug build has no Dart AOT'
);
// There's still an App.framework with a dylib, but it's empty.
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
));
final
String
debugAppFrameworkPath
=
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
);
final
String
aotSymbols
=
await
dylibSymbols
(
debugAppFrameworkPath
);
if
(
aotSymbols
.
contains
(
'architecture'
)
||
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework contains AOT'
);
}
await
_checkFrameworkArchs
(
debugAppFrameworkPath
,
'Debug'
);
// Xcode changed the name of this generated directory in Xcode 12.
const
String
xcode11ArmDirectoryName
=
'ios-armv7_arm64'
;
const
String
xcode12ArmDirectoryName
=
'ios-arm64_armv7'
;
final
String
xcode11AppFrameworkDirectory
=
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
xcode11ArmDirectoryName
,
'App.framework'
,
'App'
,
);
final
String
xcode12AppFrameworkDirectory
=
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
xcode12ArmDirectoryName
,
'App.framework'
,
'App'
,
);
// This seemed easier than an explicit Xcode version check.
String
xcodeArmDirectoryName
;
if
(
exists
(
File
(
xcode11AppFrameworkDirectory
)))
{
xcodeArmDirectoryName
=
xcode11ArmDirectoryName
;
}
else
if
(
exists
(
File
(
xcode12AppFrameworkDirectory
)))
{
xcodeArmDirectoryName
=
xcode12ArmDirectoryName
;
}
else
{
throw
const
FileSystemException
(
'Expected App.framework binary to exist.'
);
}
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
xcodeArmDirectoryName
,
'Flutter.framework'
,
'Flutter'
,
));
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
'ios-x86_64-simulator'
,
'Flutter.framework'
,
'Flutter'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
}
}
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
section
(
"Check all modes' engine header"
);
section
(
'Check profile, release builds has Dart AOT dylib'
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Headers'
,
'Flutter.h'
));
}
for
(
final
String
mode
in
<
String
>[
'Profile'
,
'Release'
])
{
final
String
appFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'App'
,
);
section
(
'Check all modes have plugins'
);
await
_checkFrameworkArchs
(
appFrameworkPath
,
mode
);
await
_checkBitcode
(
appFrameworkPath
,
mode
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
pluginFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.framework'
,
'device_info'
,
);
await
_checkFrameworkArchs
(
pluginFrameworkPath
,
mode
);
await
_checkBitcode
(
pluginFrameworkPath
,
mode
);
final
String
aotSymbols
=
await
dylibSymbols
(
appFrameworkPath
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
xcodeArmDirectoryName
,
'device_info.framework'
,
'device_info'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
xcodeArmDirectoryName
,
'device_info.framework'
,
'Headers'
,
'DeviceInfoPlugin.h'
,
));
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
'ios-x86_64-simulator'
,
'device_info.framework'
,
'device_info'
,
);
final
String
simulatorFrameworkHeaderPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
'ios-x86_64-simulator'
,
'device_info.framework'
,
'Headers'
,
'DeviceInfoPlugin.h'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
checkFileExists
(
simulatorFrameworkHeaderPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
checkFileNotExists
(
simulatorFrameworkHeaderPath
);
}
}
if
(!
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework missing Dart AOT'
);
}
section
(
'Check all modes have generated plugin registrant'
);
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
xcodeArmDirectoryName
,
'App.framework'
,
'App'
,
));
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
}
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
registrantFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'FlutterPluginRegistrant'
);
section
(
"Check all modes' engine dylib"
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
engineFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Flutter'
,
);
await
_checkFrameworkArchs
(
engineFrameworkPath
,
mode
);
await
_checkBitcode
(
engineFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
xcodeArmDirectoryName
,
'Flutter.framework'
,
'Flutter'
,
));
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
'ios-x86_64-simulator'
,
'Flutter.framework'
,
'Flutter'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
}
}
await
_checkFrameworkArchs
(
registrantFrameworkPath
,
mode
);
await
_checkBitcode
(
registrantFrameworkPath
,
mode
);
section
(
"Check all modes' engine header"
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
xcodeArmDirectoryName
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
final
String
simulatorHeaderPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
'ios-x86_64-simulator'
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorHeaderPath
);
}
else
{
checkFileNotExists
(
simulatorHeaderPath
);
}
}
// This builds all build modes' frameworks by default
section
(
'Build podspec'
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Headers'
,
'Flutter.h'
));
}
const
String
cocoapodsOutputDirectoryName
=
'flutter-frameworks-cocoapods'
;
section
(
'Check all modes have plugins'
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
pluginFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.framework'
,
'device_info'
,
);
await
_checkFrameworkArchs
(
pluginFrameworkPath
,
mode
);
await
_checkBitcode
(
pluginFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
xcodeArmDirectoryName
,
'device_info.framework'
,
'device_info'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
xcodeArmDirectoryName
,
'device_info.framework'
,
'Headers'
,
'DeviceInfoPlugin.h'
,
));
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
'ios-x86_64-simulator'
,
'device_info.framework'
,
'device_info'
,
);
final
String
simulatorFrameworkHeaderPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
'ios-x86_64-simulator'
,
'device_info.framework'
,
'Headers'
,
'DeviceInfoPlugin.h'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
checkFileExists
(
simulatorFrameworkHeaderPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
checkFileNotExists
(
simulatorFrameworkHeaderPath
);
}
}
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios-framework'
,
'--cocoapods'
,
'--universal'
,
'--force'
,
// Allow podspec creation on master.
'--output=
$cocoapodsOutputDirectoryName
'
],
);
});
section
(
'Check all modes have generated plugin registrant'
);
final
String
cocoapodsOutputPath
=
path
.
join
(
projectDir
.
path
,
cocoapodsOutputDirectoryName
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'Flutter.podspec'
,
));
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
if
(!
isModule
)
{
continue
;
}
final
String
registrantFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'FlutterPluginRegistrant'
);
await
_checkFrameworkArchs
(
registrantFrameworkPath
,
mode
);
await
_checkBitcode
(
registrantFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
xcodeArmDirectoryName
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
final
String
simulatorHeaderPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
'ios-x86_64-simulator'
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorHeaderPath
);
}
else
{
checkFileNotExists
(
simulatorHeaderPath
);
}
}
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'App.framework'
,
));
// This builds all build modes' frameworks by default
section
(
'Build podspec'
);
const
String
cocoapodsOutputDirectoryName
=
'flutter-frameworks-cocoapods'
;
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios-framework'
,
'--cocoapods'
,
'--universal'
,
'--force'
,
// Allow podspec creation on master.
'--output=
$cocoapodsOutputDirectoryName
'
],
);
});
checkDirectoryExists
(
path
.
join
(
final
String
cocoapodsOutputPath
=
path
.
join
(
projectDir
.
path
,
cocoapodsOutputDirectoryName
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'Flutter.podspec'
,
));
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'App.framework'
,
));
if
(
Directory
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
));
)).
existsSync
()
!=
isModule
)
{
throw
TaskResult
.
failure
(
'Unexpected FlutterPluginRegistrant.framework.'
);
}
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'device_info.framework'
,
));
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'device_info.framework'
,
));
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'package_info.framework'
,
));
}
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'package_info.framework'
,
));
}
if
(
File
(
path
.
join
(
outputPath
,
'GeneratedPluginRegistrant.h'
,
)).
existsSync
()
==
isModule
)
{
throw
TaskResult
.
failure
(
'Unexpected GeneratedPluginRegistrant.h.'
);
}
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
if
(
File
(
path
.
join
(
outputPath
,
'GeneratedPluginRegistrant.m'
,
)).
existsSync
()
==
isModule
)
{
throw
TaskResult
.
failure
(
'Unexpected GeneratedPluginRegistrant.m.'
);
}
}
Future
<
void
>
_checkFrameworkArchs
(
String
frameworkPath
,
String
mode
)
async
{
...
...
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
View file @
be2e7bb1
...
...
@@ -113,7 +113,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
final
String
name
=
'ios-framework'
;
@override
final
String
description
=
'Produces
a .framework directory for a Flutter module
'
final
String
description
=
'Produces
.frameworks for a Flutter project
'
'and its plugins for integration into existing, plain Xcode projects.
\n
'
'This can only be run on macOS hosts.'
;
...
...
@@ -144,10 +144,6 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
Future
<
void
>
validateCommand
()
async
{
await
super
.
validateCommand
();
_project
=
FlutterProject
.
current
();
if
(!
_project
.
isModule
)
{
throwToolExit
(
'Building frameworks for iOS is only supported from a module.'
);
}
if
(!
_platform
.
isMacOS
)
{
throwToolExit
(
'Building frameworks for iOS is only supported on the Mac.'
);
}
...
...
@@ -178,7 +174,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
}
if
(!
_project
.
ios
.
existsSync
())
{
throwToolExit
(
'
Module
does not support iOS'
);
throwToolExit
(
'
Project
does not support iOS'
);
}
final
Directory
outputDirectory
=
globals
.
fs
.
directory
(
globals
.
fs
.
path
.
absolute
(
globals
.
fs
.
path
.
normalize
(
outputArgument
)));
...
...
@@ -233,6 +229,23 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
}
globals
.
printStatus
(
'Frameworks written to
${outputDirectory.path}
.'
);
if
(!
_project
.
isModule
&&
hasPlugins
(
_project
))
{
// Apps do not generate a FlutterPluginRegistrant.framework. Users will need
// to copy the GeneratedPluginRegistrant class to their project manually.
final
File
pluginRegistrantHeader
=
_project
.
ios
.
pluginRegistrantHeader
;
final
File
pluginRegistrantImplementation
=
_project
.
ios
.
pluginRegistrantImplementation
;
pluginRegistrantHeader
.
copySync
(
outputDirectory
.
childFile
(
pluginRegistrantHeader
.
basename
).
path
);
pluginRegistrantImplementation
.
copySync
(
outputDirectory
.
childFile
(
pluginRegistrantImplementation
.
basename
)
.
path
);
globals
.
printStatus
(
'
\n
Copy the
${globals.fs.path.basenameWithoutExtension(pluginRegistrantHeader.path)}
class into your project.
\n
'
'See https://flutter.dev/docs/development/add-to-app/ios/add-flutter-screen#create-a-flutterengine for more information.'
);
}
return
FlutterCommandResult
.
success
();
}
...
...
@@ -459,6 +472,7 @@ end
xcodeBuildConfiguration,
'
SYMROOT
=
$
{
iPhoneBuildOutput
.
path
}
',
'
BITCODE_GENERATION_MODE
=
$bitcodeGenerationMode
',
'
ENABLE_BITCODE
=
YES
', // Support host apps with bitcode enabled.
'
ONLY_ACTIVE_ARCH
=
NO
', // No device targeted, so build all valid architectures.
'
BUILD_LIBRARY_FOR_DISTRIBUTION
=
YES
',
];
...
...
@@ -483,6 +497,7 @@ end
'
-
configuration
',
xcodeBuildConfiguration,
'
SYMROOT
=
$
{
simulatorBuildOutput
.
path
}
',
'
ENABLE_BITCODE
=
YES
', // Support host apps with bitcode enabled.
'
ARCHS
=
x86_64
',
'
ONLY_ACTIVE_ARCH
=
NO
', // No device targeted, so build all valid architectures.
'
BUILD_LIBRARY_FOR_DISTRIBUTION
=
YES
',
...
...
packages/flutter_tools/lib/src/plugins.dart
View file @
be2e7bb1
...
...
@@ -897,36 +897,24 @@ Future<void> _writeIOSPluginRegistrant(FlutterProject project, List<Plugin> plug
'
framework
': '
Flutter
',
'
plugins
': iosPlugins,
};
final String registryDirectory = project.ios.pluginRegistrantHost.path;
if (project.isModule) {
final String registry
ClassesDirectory = globals.fs.path.join(registryDirectory, '
Classes
')
;
final String registry
Directory = project.ios.pluginRegistrantHost.path
;
_renderTemplateToFile(
_pluginRegistrantPodspecTemplate,
context,
globals.fs.path.join(registryDirectory, '
FlutterPluginRegistrant
.
podspec
'),
);
_renderTemplateToFile(
_objcPluginRegistryHeaderTemplate,
context,
globals.fs.path.join(registryClassesDirectory, '
GeneratedPluginRegistrant
.
h
'),
);
_renderTemplateToFile(
_objcPluginRegistryImplementationTemplate,
context,
globals.fs.path.join(registryClassesDirectory, '
GeneratedPluginRegistrant
.
m
'),
);
} else {
_renderTemplateToFile(
_objcPluginRegistryHeaderTemplate,
context,
globals.fs.path.join(registryDirectory, '
GeneratedPluginRegistrant
.
h
'),
);
_renderTemplateToFile(
_objcPluginRegistryImplementationTemplate,
context,
globals.fs.path.join(registryDirectory, '
GeneratedPluginRegistrant
.
m
'),
);
}
_renderTemplateToFile(
_objcPluginRegistryHeaderTemplate,
context,
project.ios.pluginRegistrantHeader.path,
);
_renderTemplateToFile(
_objcPluginRegistryImplementationTemplate,
context,
project.ios.pluginRegistrantImplementation.path,
);
}
/// The relative path from a project'
s
main
CMake
file
to
the
plugin
symlink
...
...
packages/flutter_tools/lib/src/project.dart
View file @
be2e7bb1
...
...
@@ -665,15 +665,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
)
);
if
(
framework
.
existsSync
())
{
final
Directory
engineDest
=
ephemeralDirectory
.
childDirectory
(
'Flutter'
)
.
childDirectory
(
'engine'
);
final
File
podspec
=
framework
.
parent
.
childFile
(
'Flutter.podspec'
);
globals
.
fsUtils
.
copyDirectorySync
(
framework
,
engine
Dest
.
childDirectory
(
'Flutter.framework'
),
engine
CopyDirectory
.
childDirectory
(
'Flutter.framework'
),
);
podspec
.
copySync
(
engine
Dest
.
childFile
(
'Flutter.podspec'
).
path
);
podspec
.
copySync
(
engine
CopyDirectory
.
childFile
(
'Flutter.podspec'
).
path
);
}
}
...
...
@@ -704,6 +701,22 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
:
hostAppRoot
.
childDirectory
(
_hostAppProjectName
);
}
File
get
pluginRegistrantHeader
{
final
Directory
registryDirectory
=
isModule
?
pluginRegistrantHost
.
childDirectory
(
'Classes'
)
:
pluginRegistrantHost
;
return
registryDirectory
.
childFile
(
'GeneratedPluginRegistrant.h'
);
}
File
get
pluginRegistrantImplementation
{
final
Directory
registryDirectory
=
isModule
?
pluginRegistrantHost
.
childDirectory
(
'Classes'
)
:
pluginRegistrantHost
;
return
registryDirectory
.
childFile
(
'GeneratedPluginRegistrant.m'
);
}
Directory
get
engineCopyDirectory
{
return
isModule
?
ephemeralDirectory
.
childDirectory
(
'Flutter'
).
childDirectory
(
'engine'
)
:
hostAppRoot
.
childDirectory
(
'Flutter'
);
}
Future
<
void
>
_overwriteFromTemplate
(
String
path
,
Directory
target
)
async
{
final
Template
template
=
await
Template
.
fromName
(
path
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment