«dyld: библиотека не загружена» с приложением, использующим мой фреймворк, который использует cocoapods - PullRequest
0 голосов
/ 28 марта 2019

Я перевожу проект macOS, чтобы у него была общая кроссплатформенная инфраструктура, которую я затем смогу использовать для создания приложений iOS и tvOS.Я разделил свой код на API и пользовательский интерфейс macOS.Но так как мой API зависит от CocoaPods, я быстро столкнулся с проблемой компоновщика:

  dyld: Library not loaded: @rpath/SwiftWebSocket.framework/Versions/A/SwiftWebSocket
  Referenced from: /Users/<my user name>/Library/Developer/Xcode/DerivedData/API-cqhjtidcxfuslhhfzzmfwzberuyg/Build/Products/Debug/API.framework/Versions/A/API
  Reason: image not found

Изучив различные ресурсы, я подумал, что смогу найти решение.Неудачно.Вот что я безуспешно попробовал:

  • Добавление фреймворка модуля непосредственно в конечное приложение в целевом «связать двоичный файл с библиотеками».Результат, "ld: framework not found SwiftWebSocket"
  • Добавление структуры модуля для копирования с ресурсами комплекта на этапе построения API-интерфейса платформы.Я думал, что, по крайней мере, я мог быть уверен, что он включен в структуру API.Результат: «Нет такого файла или каталога»
  • Установка фреймворка на «необязательный».В результате возникает проблема с отложенным связыванием.

Стоит отметить, что мой API является оберткой для этого cocoapod;Мне это вообще не нужно в приложении.Я читал хаки, которые работают, помещая ссылку в приложение, но даже они не работают для меня.

Мой уровень квалификации с настройками проекта не очень высок.Но из всех этих ошибок мне кажется, что раскрытие этого API не работает, потому что все, что ищет его - dyld, ld или процесс сборки xcode - не может его найти.Мой код компилируется и прекрасно с ним связывается.

Для чего это стоит, вот мой подфайл.Я использовал pod init для его генерации, а затем добавил то, что мне нужно:

target 'API iOS' do
    use_frameworks!
    pod 'SwiftWebSocket', '~> 2.7'
    pod 'SwiftySound'
end

target 'API macOS' do
    use_frameworks!
    pod 'SwiftWebSocket', '~> 2.7'
    pod 'SwiftySound'
end

target 'API tvOS' do
    use_frameworks!
    pod 'SwiftWebSocket', '~> 2.7'
    pod 'SwiftySound'
end

Я потратил четыре часа на это, и я очень расстроен.Любые указатели оценены!

РЕДАКТИРОВАТЬ: В дополнение к этому, вот некоторый анализ, как я узнаю, как настройки сборки влияют на динамически загружаемые пути.Я учусь здесь в режиме реального времени, поэтому, если что-то не так, пожалуйста, дайте мне знать.

Разбирая ошибку, первая часть говорит:

dyld: Library not loaded: @rpath/SwiftWebSocket.framework/Versions/A/SwiftWebSocket

Это означает, что динамический ldне может загрузить библиотеку SwiftWebSocket, одну из модулей, которую он ожидает найти по этому пути.

@rpath настраивается в настройках сборки как база имен установки динамической библиотеки.Значения по умолчанию задаются в параметре «Пути поиска пути выполнения» LD_RUNPATH_SEARCH_PATHS, '@executable_path/../Frameworks' и '@loader_path/Frameworks'.

Следующая часть ошибки гласит:

  Referenced from: /Users/<my user name>/Library/Developer/Xcode/DerivedData/API-cqhjtidcxfuslhhfzzmfwzberuyg/Build/Products/Debug/API.framework/Versions/A/API

путь к моей пользовательской среде, которую я обертываю вокруг SwiftWebSocket.

Сама ошибка - Reason: image not found, которую я принимаю за ошибку «файл не найден».Таким образом, чтобы выяснить, в чем заключается проблема, нужно увидеть, как эти пути не разрешаются в SwiftWebSocket.

Итак, давайте разрешим эти два @rpath вручную.

Я думаю @executable_path означает путь к моей пользовательской платформе, на который есть ссылка выше.Таким образом, это означает, что первый @rpath будет на один каталог выше, чем остальные после:

/Users/<my user name>/Library/Developer/Xcode/DerivedData/API-cqhjtidcxfuslhhfzzmfwzberuyg/Build/Products/Debug/API.framework/Versions/Frameworks

... но это не относится к инфраструктуре SwiftWebSocket.Далее @rpath содержит @loader_path.Опять же, я продолжаю то, к чему я думаю это разрешает, и похоже, что оно @executable_path.Так что это будет означать, что это будет:

/Users/<my user name>/Library/Developer/Xcode/DerivedData/API-cqhjtidcxfuslhhfzzmfwzberuyg/Build/Products/Debug/API.framework/Versions/A/Frameworks

Который тоже не имеет.Так что, по крайней мере, мы доказали, что это не то, куда смотрит.Где он равен , находится по адресу:

/Users/<my user name>/Library/Developer/Xcode/DerivedData/API-cqhjtidcxfuslhhfzzmfwzberuyg/Build/Products/Debug/SwiftWebSocket-macOS

Поэтому, чтобы узнать, смогу ли я запустить приложение, я скопировал фреймворк в '@loader_path/Frameworks'.Мне нужно было создать папку Frameworks.Это сработало, но это не решение.Теперь я собираюсь создать новую запись @rpath, которая будет отображаться там, где она есть на самом деле:

@loader_path/../../../SwiftWebSocket-macOS

Я также создал запись для SwiftySound, которая также проблематична.

@loader_path/../../../SwiftySound-macOS/

И... это работает

Однако, это правильный способ сделать это?Я не могу помочь, но думаю, что есть более элегантное решение для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...