Мобильная разработка

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.

5 ответов 1 просмотр

Почему приложение 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-режиме

Представьте: вы дописываете нативный 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:

  1. Перетащите XCFramework в Xcode проект (Runner > Frameworks).
  2. В Build Phases > Link Binary With Libraries добавьте.
  3. Embed & Sign вручную.
  4. В 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

Финальный чеклист:

  1. flutter build ios --release --no-codesign
  2. Xcode > Archive > Distribute App > Ad-hoc.
  3. Установите .ipa на устройство (AltStore или Xcode).
  4. Запустите, вызовите C++ функцию с libavcodec — должно работать.
  5. Проверьте размер .ipa: XCFramework добавит ~50-100MB, оптимизируйте strip.

Инструменты: FFmpeg iOS builds, lipo, nm для символов.

Если краш остался — логи через device support в Xcode. Успех!


Источники

  1. Stack Overflow — Решение dyld ошибки с libavcodec в Flutter iOS release: https://stackoverflow.com/questions/75128012/dyld16458-library-not-loaded-rpath-libavcodec-framework-libavcodec-while-ru
  2. 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
  3. Sarunw — Руководство по фиксу dyld Library not loaded @rpath в iOS: https://sarunw.com/posts/how-to-fix-dyld-library-not-loaded-error/
  4. 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!

S

В 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.

M

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-краша.

S

Ошибка 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-конфигураций.

Cayley Humphries / Разработчик

При 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.

Авторы
S
Разработчик
M
Разработчик
S
iOS-разработчик
Cayley Humphries / Разработчик
Разработчик
Проверено модерацией
НейроОтветы
Модерация
Flutter iOS крашится в release с libavcodec: фикс dyld