Skip to content

xcodebuild clean fails when using SwiftPM and a custom BUILD_DIR #183006

Description

@vashworth

xcodebuild clean fails when SwiftPM has been integrated into the app.

  1. flutter config --no-enable-swift-package-manager
  2. flutter create my_app --platforms ios && cd my_app
  3. flutter pub add image_picker
  4. flutter build ios
  5. xattr -l build/ios
    • Expected & Actual output: nothing
  6. xattr -l build/ios/iphoneos
    • Expected & Actual output: nothing
  7. xattr -l build/ios/Release-iphoneos
    • Expected & Actual output: com.apple.xcode.CreatedByBuildSystem: true
  8. cd ios && xcodebuild clean -scheme Runner -workspace Runner.xcworkspace -configuration Release -sdk iphoneos -destination "generic/platform=iOS" BUILD_DIR="../build/ios"
    • Expected & Actual output: ** CLEAN SUCCEEDED **
    • If you check ls ../build/ios, you will see Release-iphoneos was deleted
  9. flutter config --enable-swift-package-manager
  10. cd .. && flutter clean
  11. flutter build ios
  12. xattr -l build/ios
    • Expected output: nothing
    • Actual output: com.apple.xcode.CreatedByBuildSystem: true
  13. xattr -l build/ios/iphoneos
    • Expected & Actual output: nothing
  14. xattr -l build/ios/Release-iphoneos
    • Expected output: com.apple.xcode.CreatedByBuildSystem: true
    • Actual output: nothing
  15. cd ios && xcodebuild clean -scheme Runner -workspace Runner.xcworkspace -configuration Release -sdk iphoneos -destination "generic/platform=iOS" BUILD_DIR="../build/ios"
    • Expected output: ** CLEAN SUCCEEDED **
    • Actual output:
error: Could not delete `/path/to/my_app/build/ios/Release-iphoneos` because it was not created by the build system and it is not a subfolder of derived data.
    note: To mark this directory as deletable by the build system, run `xattr -w com.apple.xcode.CreatedByBuildSystem true /path/to/my_app/build/ios/Release-iphoneos` when it is created.
** CLEAN FAILED **

This is a problem for Flutter because we use clean when engine headers change:

// Xcode 26 changed the way headers are pre-compiled and will throw an error if the headers
// have changed since the last time they were compiled. To avoid this error, clean before
// building if headers have changed.
targetBuildDir.deleteSync(recursive: true);
buildCommands.addAll(<String>['clean', 'build']);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions