1

I'm trying to set up a build pipeline on Azure DevOps for my flutter project. The android build works but the iOS build is giving "fatal error: 'Flutter/Flutter.h' file not found".

This is my pipeline:

trigger:
  - develop

pool:
  vmImage: 'macOS-10.15'

steps:
  - task: FlutterInstall@0
    displayName: Install Flutter $(FLUTTER_VERSION)
    inputs:
      channel: 'stable'
      version: 'custom'
      customVersion: $(FLUTTER_VERSION)
  - task: InstallAppleCertificate@2
    displayName: Install Apple Certificate
    inputs:
      certSecureFile: $(APPLE_CERTIFICATE_FILE)
      certPwd: '$(APPLE_CERTIFICATE_PASSWORD)'
      keychain: 'temp'
  - task: InstallAppleProvisioningProfile@1
    displayName: Install Apple Provisioning Profile
    inputs:
      provisioningProfileLocation: 'secureFiles'
      provProfileSecureFile: $(APPLE_PROVISIONINGPROFILE_FILE)
  - bash: |
      set -e ; set -o pipefail
      $(FlutterToolPath)/flutter clean
      $(FlutterToolPath)/flutter pub get
      
      ##################################
      cd ios
      pod install
      xcodebuild -workspace Runner.xcworkspace -scheme dev -destination 'generic/platform=iOS'
      cd ..
      ##################################

      $(FlutterToolPath)/flutter build ios --flavor dev -t lib/main.dart --no-sound-null-safety # build breaks here
      $(FlutterToolPath)/flutter build apk --flavor dev -t lib/main.dart --no-sound-null-safety

Here FLUTTER_VERSION is 2.0.5, and the certificate and provisioning files come from the Azure Pipelines Library. They are all found and the installation steps are working correctly.

Everything works until flutter build ios, which gives said error. I had the same issue a while ago on my MacBook Pro and I fixed it by opening the ios project with XCode and running Product => Build, the lines enclosed in hashes were added to mimic that behaviour but I'm not 100% sure they are correct.

What I tried:

  • I tried adding the lines enclosed with hashes in an attempt to mimic the "Product => Build" XCode feature, which solved this issue on my MacBook Pro a while ago. This isn't working though, the build is fine but then the flutter build command fails with the same error.
  • I tried the solution proposed in the answer to this question, however it's not applicable in my scenario because these files are not pushed to the repository thus they don't actually exist
  • I tried the solution proposed in the answer to this question but again, this file doesn't exist on the repository.

The weird thing here is that on the MacBook Pro I had this issue once and I resolved it with the "Product => Build" feature. I can easily build the iOS package on my MacBook so I'm thinking there might be some configuration in my MacBook that flutter/xcode aren't finding in the isolated pipeline environment.

The relevant part of the log:

CompileC /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/Objects-normal/armv7/FLTFirebaseCrashlyticsPlugin.o /Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_crashlytics-0.4.0+1/ios/Classes/FLTFirebaseCrashlyticsPlugin.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'firebase_crashlytics' from project 'Pods')
    cd /Users/runner/work/1/s/ios/Pods
    export LANG\=en_US.US-ASCII
    /Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -target armv7-apple-ios10.0 -fmessage-length\=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit\=0 -std\=gnu11 -fobjc-arc -fmodules -gmodules -fmodules-cache-path\=/Users/runner/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval\=86400 -fmodules-prune-after\=345600 -fbuild-session-file\=/Users/runner/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror\=non-modular-include-in-framework-module -fmodule-name\=firebase_crashlytics -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror\=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror\=deprecated-objc-isa-usage -Wno-objc-interface-ivars -Werror\=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -DPOD_CONFIGURATION_DEBUG_DEV\=1 -DDEBUG\=1 -DCOCOAPODS\=1 -DLIBRARY_VERSION\=@\"0.4.0-1\" -DLIBRARY_NAME\=@\"flutter-fire-cls\" -DPERMISSION_EVENTS\=0 -DPERMISSION_REMINDERS\=0 -DPERMISSION_CONTACTS\=0 -DPERMISSION_MICROPHONE\=0 -DPERMISSION_SPEECH_RECOGNIZER\=0 -DPERMISSION_PHOTOS\=0 -DPERMISSION_LOCATION\=0 -DPERMISSION_NOTIFICATIONS\=0 -DPERMISSION_MEDIA_LIBRARY\=0 -DPERMISSION_SENSORS\=0 -DOBJC_OLD_DISPATCH_PROTOTYPES\=0 -isysroot /Applications/Xcode_12.4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wno-semicolon-before-method-body -Wunguarded-availability -fembed-bitcode-marker -index-store-path /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Index/DataStore -iquote /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/firebase_crashlytics-generated-files.hmap -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/firebase_crashlytics-own-target-headers.hmap -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/firebase_crashlytics-all-non-framework-target-headers.hmap -ivfsoverlay /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/all-product-headers.yaml -iquote /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/firebase_crashlytics-project-headers.hmap -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/firebase_crashlytics/include -I/Users/runner/work/1/s/ios/Pods/Headers/Public -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/DerivedSources-normal/armv7 -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/DerivedSources/armv7 -I/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/DerivedSources -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/firebase_crashlytics -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseCore -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseCoreDiagnostics -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseCrashlytics -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseDynamicLinks -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseInstallations -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseInstanceID -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/FirebaseMessaging -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/GoogleDataTransport -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/GoogleUtilities -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/PromisesObjC -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/firebase_core -F/Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Products/Debug-dev-iphoneos/nanopb -F/Users/runner/work/1/s/ios/Pods/FirebaseAnalytics/Frameworks -F/Users/runner/work/1/s/ios/Pods/GoogleAppMeasurement/Frameworks -include /Users/runner/work/1/s/ios/Pods/Target\ Support\ Files/firebase_crashlytics/firebase_crashlytics-prefix.pch -MMD -MT dependencies -MF /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/Objects-normal/armv7/FLTFirebaseCrashlyticsPlugin.d --serialize-diagnostics /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/Objects-normal/armv7/FLTFirebaseCrashlyticsPlugin.dia -c /Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_crashlytics-0.4.0+1/ios/Classes/FLTFirebaseCrashlyticsPlugin.m -o /Users/runner/Library/Developer/Xcode/DerivedData/Runner-gsjhxdjmxuzkkbgjdidjocbaqrkc/Build/Intermediates.noindex/Pods.build/Debug-dev-iphoneos/firebase_crashlytics.build/Objects-normal/armv7/FLTFirebaseCrashlyticsPlugin.o
In file included from /Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_crashlytics-0.4.0+1/ios/Classes/FLTFirebaseCrashlyticsPlugin.m:5:
/Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_crashlytics-0.4.0+1/ios/Classes/FLTFirebaseCrashlyticsPlugin.h:8:9: fatal error: 'Flutter/Flutter.h' file not found
#import <Flutter/Flutter.h>
        ^~~~~~~~~~~~~~~~~~~
While building module 'firebase_core' imported from /Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_crashlytics-0.4.0+1/ios/Classes/FLTFirebaseCrashlyticsPlugin.h:12:
In file included from <module-includes>:1:
In file included from /Users/runner/work/1/s/ios/Pods/Target Support Files/firebase_core/firebase_core-umbrella.h:13:
/Users/runner/hostedtoolcache/Flutter/2.0.5-stable/macos/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.7.0/ios/Classes/FLTFirebaseCorePlugin.h:8:9: fatal error: 'Flutter/Flutter.h' file not found
#import <Flutter/Flutter.h>
        ^~~~~~~~~~~~~~~~~~~
1 error generated.
2 errors generated.

Any clues?

BackSlash
  • 21,927
  • 22
  • 96
  • 136

1 Answers1

1

After several hours of trial and error I finally solved the issue. Turned out I had to do two things:

  • Run flutter version at the beginning of the pipeline.
  • Put Flutter's bin directory in the system PATH before building for iOS.

I honestly don't know what magic is happening behind but I suspect that flutter version internally checks if all the libararies and binaries are correctly downloaded and fixes this silently, while updating the PATH variable gives flutter/xcodebuild the right path to find the required files. I'm not sure about this though.

This is the updated pipeline:

trigger:
  - develop

pool:
  vmImage: 'macOS-10.15'

steps:
  - task: FlutterInstall@0
    displayName: Install Flutter $(FLUTTER_VERSION)
    inputs:
      channel: 'stable'
      version: 'custom'
      customVersion: $(FLUTTER_VERSION)
  - task: InstallAppleCertificate@2
    displayName: Install Apple Certificate
    inputs:
      certSecureFile: $(APPLE_CERTIFICATE_FILE)
      certPwd: '$(APPLE_CERTIFICATE_PASSWORD)'
      keychain: 'temp'
  - task: InstallAppleProvisioningProfile@1
    displayName: Install Apple Provisioning Profile
    inputs:
      provisioningProfileLocation: 'secureFiles'
      provProfileSecureFile: $(APPLE_PROVISIONINGPROFILE_FILE)
  - bash: |
      set -e ; set -o pipefail
      $(FlutterToolPath)/flutter --version
      export PATH=$PATH:$(FlutterToolPath)
      $(FlutterToolPath)/flutter clean
      $(FlutterToolPath)/flutter pub get
      $(FlutterToolPath)/flutter build ios --flavor dev -t lib/main.dart --no-sound-null-safety
      $(FlutterToolPath)/flutter build apk --flavor dev -t lib/main.dart --no-sound-null-safety
BackSlash
  • 21,927
  • 22
  • 96
  • 136