Я перевожу проект 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/
И... это работает
Однако, это правильный способ сделать это?Я не могу помочь, но думаю, что есть более элегантное решение для этого.