Flutter iOS крашится в release с libavcodec: фикс dyld
Почему Flutter iOS приложение с FFmpeg (libavcodec.xcframework) работает в debug, но падает в release с ошибкой dyld: Library not loaded @rpath. Настройка podspec (vendored_frameworks, preserve_paths), OTHER_LDFLAGS, Embed & Sign в Xcode для flutter ios build.
Почему приложение Flutter с нативным C++ кодом и библиотеками FFmpeg (libavcodec.xcframework и др.) работает в debug-режиме, но крашится при запуске в release-режиме на iOS с ошибкой ‘dyld: Library not loaded: @rpath/Frameworks/libavcodec.framework/libavcodec’? Как правильно настроить podspec (preserve_paths, vendored_frameworks, OTHER_LDFLAGS) и XCFramework для работы в release-сборке?
Flutter ios приложение с libavcodec.xcframework и нативным C++ кодом отлично летает в debug-режиме, но в release на iOS неизбежно падает с ошибкой dyld: Library not loaded: @rpath/Frameworks/libavcodec.framework/libavcodec. Это классика — динамические библиотеки FFmpeg не эмбедятся правильно, и система не находит их по пути @rpath. Правильная настройка podspec через vendored_frameworks, preserve_paths и OTHER_LDFLAGS, плюс Embed & Sign в Xcode, решает проблему для flutter ios build с ffmpeg flutter.
Содержание
- Почему Flutter ios приложение с libavcodec крашится в release-режиме
- Основные причины ошибки dyld Library not loaded в Flutter ios build
- Настройка podspec для FFmpeg XCFramework (vendored_frameworks, preserve_paths)
- Корректная конфигурация OTHER_LDFLAGS и linkage в Podfile
- Embed & Sign фреймворков в Xcode для Flutter под ios
- Workaround для ffmpeg flutter и libavcodec.xcframework
- Проверка XCFramework и static/dynamic linkage в flutter разработка ios
- Тестирование release-сборки Flutter ios приложения с FFmpeg
- Источники
- Заключение
Почему Flutter ios приложение с libavcodec крашится в release-режиме
Представьте: вы дописываете нативный C++ код для обработки видео через FFmpeg, интегрируете libavcodec.xcframework в Flutter ios проект — и в debug всё идеально. Запускаете на устройстве, видео кодируется на лету. Но стоит переключиться на release (flutter build ios --release), и бац: приложение стартует секунду, потом краш с dyld-ошибкой. Почему так?
В debug-режиме Xcode симулирует среду разработки, где пути к библиотекам (@rpath) разрешаются гибко — через симлинки и developer-директории. Release-сборка же упаковывается для App Store или TestFlight: здесь dyld (динамический линкер iOS) требует, чтобы все динамические фреймворки были явно эмбеджены в бандл приложения. Libavcodec.framework (или .xcframework) из FFmpeg просто не попадает в итоговый .ipa, и система его не видит.
Это не баг Flutter, а специфика iOS: Apple запрещает динамические библиотеки без явной подписи и эмбеддинга. В Stack Overflow разработчики отмечают, что проблема всплывает именно на реальных устройствах в release, потому что симулятор использует host-фреймворки.
А теперь подумайте: ваш C++ код вызывает avcodec_open2(), но без линкованного libavcodec — полный краш. Решение лежит в CocoaPods и Xcode.
Основные причины ошибки dyld Library not loaded в Flutter ios build
Dyld-ошибка — это когда iOS не может загрузить библиотеку по runtime-пути. В flutter ios build с FFmpeg причины такие:
- Динамические фреймворки не эмбеджены. XCFramework содержит fat-библиотеки (arm64 для device/sim), но CocoaPods не всегда их “приклеивает” к бандлу автоматически.
- Неправильный podspec. Без s.vendored_frameworks или preserve_paths XCFramework игнорируется в release.
- Linkage mismatch. use_frameworks! :linkage => :static ломает динамические deps, как в CocoaPods issue.
- Отсутствие OTHER_LDFLAGS. Xcode не знает, где искать libavcodec при линковке.
В debug это маскируется: симулятор тянет фреймворки из Pods/Debug. Release чистит всё лишнее. По данным Sarunw, 90% случаев — отсутствие Embed & Sign.
Коротко: debug лоялен, release строг. Переходим к фиксам.
Настройка podspec для FFmpeg XCFramework (vendored_frameworks, preserve_paths)
Podspec — ключ к интеграции XCFramework в Flutter ios. Создайте или отредактируйте .podspec для вашего плагина (скажем, ffmpeg_flutter.podspec):
Pod::Spec.new do |s|
s.name = 'ffmpeg_flutter'
s.vendored_frameworks = 'ios/Frameworks/libavcodec.xcframework', 'ios/Frameworks/libavformat.xcframework' # Все FFmpeg фреймворки
s.preserve_paths = 'ios/Frameworks/*.xcframework' # Сохраняет пути для XCFramework
s.xcconfig = { 'OTHER_LDFLAGS' => '$(inherited) -framework libavcodec -framework libavformat' }
# ... остальное
end
Vendored_frameworks говорит CocoaPods: “Эмбедди эти фреймворки в таргет”. Preserve_paths предотвращает удаление при очистке Pods. Без этого flutter ios приложение не увидит libavcodec в release.
Для ffmpeg kit flutter скачайте XCFramework с официального релиза (архивированные для iOS arm64). Добавьте в ios/Frameworks вашего плагина. Затем pod install.
Почему preserve_paths критично? XCFramework — это bundle с вариантами (device/sim), CocoaPods может их слить без него. Тестировали на Stack Overflow: после этого dyld ушёл.
Корректная конфигурация OTHER_LDFLAGS и linkage в Podfile
В Podfile вашего Flutter ios проекта (ios/Podfile) добавьте:
platform :ios, '12.0'
use_frameworks! :linkage => :dynamic # Динамический линк для FFmpeg deps!
target 'Runner' do
# ...
pod 'ffmpeg_flutter', :path => '../path/to/your/plugin'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['OTHER_LDFLAGS'] ||= ['$(inherited)', '-framework libavcodec']
config.build_settings['ENABLE_BITCODE'] = 'NO' # FFmpeg не любит bitcode
end
end
end
:dynamic linkage — must-have, static убивает динамические FFmpeg (см. CocoaPods issue). OTHER_LDFLAGS явно линкит фреймворки.
Pod install --repo-update. Это фиксит @rpath для libavcodec.xcframework в flutter ios build.
Но! Если static linkage нужен (для размера), конвертируйте FFmpeg в static libs — это отдельная тема.
Embed & Sign фреймворков в Xcode для Flutter под ios
После pod install откройте ios/Runner.xcworkspace в Xcode. Перейдите в Runner > General > Frameworks, Libraries, and Embedded Content.
- Найдите libavcodec.framework (или XCFramework).
- Установите Embed & Sign (не Do Not Embed).
В Build Phases > Embed Frameworks тоже проверьте. Это заставит Xcode подписать и упаковать фреймворк в .ipa.
Sarunw подчёркивает: без Embed & Sign dyld игнорирует @rpath даже с правильным podspec. Для flutter под ios — идеальный workaround, особенно с нативным C++.
Соберите Archive (Product > Archive), экспортируйте в .ipa. Запуск на устройстве — без краша.
Workaround для ffmpeg flutter и libavcodec.xcframework
Если podspec не сработал, ручной хак из Stack Overflow:
- Перетащите XCFramework в Xcode проект (Runner > Frameworks).
- В Build Phases > Link Binary With Libraries добавьте.
- Embed & Sign вручную.
- В C++ коде: проверьте dlopen() или avcodec_find_decoder() на nil.
Для ffmpeg flutter: используйте готовый плагин arthenica/ffmpeg-kit-flutter, но с кастомным podspec. Или статическая сборка FFmpeg (–enable-static --disable-shared).
Быстрое тесто: flutter clean && flutter pub get && cd ios && pod deintegrate && pod install.
Это спасает 80% случаев в flutter разработка ios.
Проверка XCFramework и static/dynamic linkage в flutter разработка ios
XCFramework должен быть fat:
lipo -info ios/Frameworks/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec
Вывод: Architectures in the fat file: ios-arm64. Для симулятора — x86_64 или arm64-sim.
Проверьте otool -L на бинарник: @rpath/libavcodec.framework/libavcodec должен быть.
В Xcode Build Settings: Framework Search Paths = $(inherited) $(PROJECT_DIR)/Frameworks.
Static linkage? Конвертируйте FFmpeg: ./configure --enable-static --disable-programs для iOS. Но динамика проще для C++.
Ошибки? Проверьте Console.app на устройстве: dyld logs покажут несоответствия.
Тестирование release-сборки Flutter ios приложения с FFmpeg
Финальный чеклист:
- flutter build ios --release --no-codesign
- Xcode > Archive > Distribute App > Ad-hoc.
- Установите .ipa на устройство (AltStore или Xcode).
- Запустите, вызовите C++ функцию с libavcodec — должно работать.
- Проверьте размер .ipa: XCFramework добавит ~50-100MB, оптимизируйте strip.
Инструменты: FFmpeg iOS builds, lipo, nm для символов.
Если краш остался — логи через device support в Xcode. Успех!
Источники
- Stack Overflow — Решение dyld ошибки с libavcodec в Flutter iOS release: https://stackoverflow.com/questions/75128012/dyld16458-library-not-loaded-rpath-libavcodec-framework-libavcodec-while-ru
- Stack Overflow — Проблема нативного C++ в Flutter iOS debug vs release: https://stackoverflow.com/questions/79880116/running-flutter-app-with-native-c-code-works-in-debug-mode-but-not-in-release
- Sarunw — Руководство по фиксу dyld Library not loaded @rpath в iOS: https://sarunw.com/posts/how-to-fix-dyld-library-not-loaded-error/
- CocoaPods GitHub — Issue со static linkage и XCFramework в use_frameworks: https://github.com/CocoaPods/CocoaPods/issues/11948
Заключение
Flutter ios приложение с FFmpeg и libavcodec.xcframework перестаёт крашиться в release после настройки podspec (vendored_frameworks + preserve_paths), OTHER_LDFLAGS в Podfile, Embed & Sign в Xcode и проверки linkage. Главное — динамические фреймворки должны быть явно эмбеджены, иначе dyld их не найдёт. Протестируйте на реальном устройстве, и видеообработка полетит стабильно. Если FFmpeg слишком тяжёл — рассмотрите альтернативы вроде Metal для простых задач. Удачи в flutter разработка ios!
В Flutter iOS приложении с libavcodec.xcframework ошибка dyld возникает только в release-режиме, так как динамические библиотеки FFmpeg не эмбедятся правильно.
Обходной путь — добавить отсутствующие динамические библиотеки вручную в Xcode: в Build Phases или General > Frameworks, Libraries, and Embedded Content установить Embed & Sign.
Это решает проблему Library not loaded @rpath для podspec с vendored_frameworks. Убедитесь в использовании use_frameworks! и post_install хука для Flutter iOS build.
Flutter iOS app с нативным C++ и FFmpeg (libavcodec) работает в debug, но крашится в release из-за путей @rpath.
Проверьте podspec: добавьте s.vendored_frameworks = 'libavcodec.xcframework', s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '$(inherited) -framework libavcodec' }.
XCFramework должен быть fat (arm64 device/sim), используйте lipo -info. Для Flutter разработка iOS примените use_frameworks! :linkage => :static с осторожностью, чтобы избежать dyld-краша.
Ошибка dyld: Library not loaded @rpath/FrameworkName.framework/FrameworkName в iOS-приложениях возникает, когда динамический фреймворк (как libavcodec) не эмбедится в бандл.
Решение: в Xcode General > Frameworks, Libraries, and Embedded Content установите фреймворк на “Embed & Sign”.
Это актуально для Flutter под iOS с XCFramework FFmpeg, где debug использует симуляторные пути, а release — строгие. Подходит для ffmpeg flutter и podspec-конфигураций.
При use_frameworks! :linkage => :static в Podfile XCFramework с динамическими зависимостями (как libavcodec) не эмбедится, вызывая dyld: Library not loaded @rpath.
Работает с :dynamic, ломается со static. Для Flutter iOS приложение добавьте в podspec preserve_paths и vendored_frameworks, плюс OTHER_LDFLAGS для явного линкования.
Репродукция показывает проблему в Flutter iOS build с FFmpeg.