-
Notifications
You must be signed in to change notification settings - Fork 29.8k
flutter_tools: Copy vendored frameworks from plugin podspecs in ios/macos-framework builds #180135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
flutter_tools: Copy vendored frameworks from plugin podspecs in ios/macos-framework builds #180135
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request adds support for copying vendored frameworks from plugin podspecs during iOS and macOS framework builds. The implementation introduces a new copyVendoredFrameworks method and a regex-based parser for podspecs. My review focuses on improving the robustness and correctness of the parsing logic, aligning with async best practices, and enhancing test clarity. Overall, this is a valuable addition that addresses a gap in the build process.
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
Outdated
Show resolved
Hide resolved
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
Outdated
Show resolved
Hide resolved
packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request adds functionality to copy vendored frameworks from plugin podspecs during iOS and macOS framework builds. The implementation introduces a new method copyVendoredFrameworks and a regex-based parser parseVendoredFrameworks.
My review focuses on improving the robustness of the podspec parsing and correcting a path resolution issue.
- The
parseVendoredFrameworksfunction has a potential bug where it could incorrectly handle multiplevendored_frameworksassignments. I've suggested a refactoring to process only the last assignment, which aligns with Ruby's behavior. - There's a path resolution bug in
copyVendoredFrameworksthat could fail for plugins with shareddarwinsources. I've provided a fix to use the podspec's parent directory as the base for resolving framework paths. - I've also recommended adding tests for the new
copyVendoredFrameworkslogic to ensure its correctness and prevent future regressions.
Overall, the changes are a valuable addition, and with these fixes, the implementation will be more robust.
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
Outdated
Show resolved
Hide resolved
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
Outdated
Show resolved
Hide resolved
packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart
Outdated
Show resolved
Hide resolved
afeee34 to
70486c6
Compare
| final Directory destination = modeDirectory.childDirectory(frameworkName); | ||
| if (!destination.existsSync()) { | ||
| globals.logger.printTrace('Copying vendored xcframework: $frameworkName'); | ||
| copyDirectory(source, destination); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vashworth do you have concerns this will cause unintended consequences when a plugin supports both CoocaPods and Swift Package Manager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm planning on introducing a new command when we do add SwiftPM support for add to app. So this will need to be adjusted (to limit it to CocoaPods-only plugins) and added to the new command, but I don't see any major conflicts
| // It captures either a single quoted string or an array literal. | ||
| // Group 1: single string content, Group 2: array content | ||
| final pattern = RegExp( | ||
| r'''^\s*[a-zA-Z_]+\.vendored_frameworks\s*=\s*(?:["']([^"']+)["']|\[([^\]]*)\])''', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not take into account when a vendored_framework is per platform, such as
spec.ios.vendored_frameworks = 'Frameworks/MyFramework.framework'
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
Outdated
Show resolved
Hide resolved
| final Directory destination = modeDirectory.childDirectory(frameworkName); | ||
| if (!destination.existsSync()) { | ||
| globals.logger.printTrace('Copying vendored xcframework: $frameworkName'); | ||
| copyDirectory(source, destination); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm planning on introducing a new command when we do add SwiftPM support for add to app. So this will need to be adjusted (to limit it to CocoaPods-only plugins) and added to the new command, but I don't see any major conflicts
| } | ||
| } else if (arrayContent != null) { | ||
| // Extract individual paths from the array content. | ||
| final pathPattern = RegExp(r'''["']([^"']+)["']'''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Podspec syntax allows wildcard patterns such as:
s.vendored_frameworks = '**/*.xcframework'
https://guides.cocoapods.org/syntax/podspec.html#group_file_patterns
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to match all the patterns seems overcomplicated. We could just try to match the most basic and accept it as a limitation for now since this would still be an improvement to what is.
I wonder if perhaps instead of parsing the podspec, the ios/Pods/Pods.xcodeproj/project.pbxproj could be parsed (using PlistParser) to find any children found in PBXGroups called "Frameworks".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be unit tests for copyVendoredFrameworks too
|
Hey, sorry for keeping you waiting on this, I switched to parsing the project.pbxproj file instead of the podspec like you suggested. This way CocoaPods handles all the wildcard and platform-specific stuff for us. |
… Darwin framework builds.
Co-authored-by: Victoria Ashworth <15619084+vashworth@users.noreply.github.com>
This change addresses reviewer feedback by: - Replacing podspec regex parsing with project.pbxproj parsing using PlistParser - This approach is more reliable because CocoaPods has already resolved all paths, wildcards, and platform-specific entries - Handles edge cases like spec.ios.vendored_frameworks and wildcard patterns automatically - Added comprehensive unit tests for parseVendoredFrameworksFromPbxproj Note: This only copies frameworks from CocoaPods-based plugins. Swift Package Manager support will be added in a separate command as mentioned by @vashworth.
50a61cc to
038add9
Compare
Fixes #125530
When running
flutter build ios-frameworkorflutter build macos-framework, vendored frameworks declared in plugin podspecs (vias.vendored_frameworks) were not being copied to the output directory.This PR adds support for parsing plugin podspecs to find vendored_frameworks entries and copying them to the output directory. Single .framework files are wrapped into xcframeworks to match the output format.
Changes:
copyVendoredFrameworksmethod toBuildFrameworkCommandbase classparseVendoredFrameworksfunction to parse podspec Ruby filesI'm happy to adjust the approach if there's a better way to handle this - particularly around the regex-based podspec parsing. Let me know if this looks reasonable or if you'd prefer a different strategy.