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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions