Как создать рабочую среду с файлами dylib в Xcode 4 - PullRequest
16 голосов
/ 27 сентября 2011

Я создал новую платформу какао в XCode, удалил все библиотеки и файлы, которые он включает в начале, кроме вспомогательных файлов.

У меня есть 2 файла:

add.h

#ifndef add_add_h
#define add_add_h

void add(void);

#endif

и

add.c
#include <stdio.h>
#include "add.h"

void add(void)
{
    printf("adfding");

}

на этапах сборки Я добавляю add.c для компиляции исходников и add.h для публичной компиляции заголовков.Сборка проекта без проблем, но в фреймворке нет файла dylib, и когда я перетаскиваю фреймворк в другой проект, он говорит, что файл dylib не найден.

dyld: Library not loaded: @rpath/add.framework/Versions/A/add 
  Referenced from: /Users/vjoukov/Desktop/Projects/test/build/Debug/test.app/Contents/MacOS/test
  Reason: image not found

Как я могу создать простой фреймворк и хранить в нем файлы dylib?

1 Ответ

61 голосов
/ 27 сентября 2011

Я думаю, вы неправильно понимаете сообщение об ошибке.

A .framework работает как динамическая библиотека, но не будет никакого загружаемого объектного файла Mach-O с фактическим .dylib расширением имени файлавнутри папки .framework.

Есть несколько причин, по которым вы можете получить это сообщение об ошибке от dyld, загрузчика динамической библиотеки, во время выполнения.Во-первых, вы забыли скопировать .frameworks в сборку приложения во время процесса сборки.Хотя их можно скопировать в любое место в комплекте приложений, традиционное место находится в AppName.app/Contents/Frameworks/.Если вы еще этого не сделали, выберите «Проект»> «Новый этап сборки»> «Новый этап создания файлов копирования».Измените всплывающее окно «Назначение» на «Каркасы», как показано на изображении ниже.

enter image description here

Затем перетащите значок каркаса в папку, чтобы он копировался в процессе сборки.

enter image description here

Вторая и более вероятная причина, по которой среда не может быть найдена во время выполнения, заключается в том, что вы не указали пути поиска пути выполнения для своего основного исполняемого файла.(Это необходимо, потому что, как мы видели из вашего сообщения об ошибке, ваша платформа была построена с использованием более нового имени установки @rpath/ (@rpath/add.framework/Versions/A/add), а не более старых @executable_path/ или @loader_path/ стилей).

Если вы скопируете пользовательские рамки в указанное выше место, вы добавите запись пути поиска пути @loader_path/../Frameworks, как показано на рисунке ниже:

enter image description here

Следующая выдержка, которая объясняет, как динамические библиотеки обнаруживаются во время выполнения, взята из справочной страницы dyld:

ДИНАМИЧНАЯ БИБЛИОТЕКА ЗАГРУЗКИ

В отличие от многих других операцийВ системах Дарвин не находит зависимые динамические библиотеки через их конечные имена файлов.Вместо этого используется полный путь к каждому dylib (например, /usr/lib/libSystem.B.dylib).Но бывают случаи, когда полный путь не подходит;например, может потребоваться установка ваших двоичных файлов в любое место на диске.Для поддержки этого есть три @xxx/ переменных, которые можно использовать в качестве префикса пути.Во время выполнения dyld заменяет динамически сгенерированный путь на префикс @xxx/.

@executable_path/

Эта переменная заменяется путем к каталогу, содержащему основной исполняемый файл процесса.Это полезно для загрузки dylibs / frameworks, встроенных в каталог .app.Если основной исполняемый файл находится в /some/path/My.app/Contents/MacOS/My, а файл dylib фреймворка - в
/some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo, то путь загрузки фреймворка может быть закодирован как @executable_path/../Frameworks/Foo.framework/Versions/A/Foo, а каталог .app можно перемещать в файловой системе иdyld по-прежнему сможет загружать встроенный каркас.

@loader_path/

Эта переменная заменяется путем к пути к каталогу, содержащему двоичный файл mach-o, который содержит команду загрузки, используя@loader_path.Таким образом, в каждом двоичном файле @loader_path разрешается по другому пути, тогда как @executable_path всегда разрешается по одному и тому же пути.@loader_path полезен в качестве пути загрузки для framework / dylib, встроенного в плагин, если окончательное местоположение файловой системы плагина неизвестно (поэтому абсолютные пути не могут использоваться) или если плагин используетсянесколько приложений (поэтому @executable_path не может быть использовано).Если файл mach-o подключаемого модуля имеет значение /some/path/Myfilter.plugin/Contents/MacOS/Myfilter, а файл dylib фреймворка - /some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo, то путь загрузки фреймворка можно кодировать как @loader_path/../Frameworks/Foo.framework/Versions/A/Foo, а каталог Myfilter.plugin можно перемещать в файле.system и dyld по-прежнему смогут загружать встроенный каркас.

@rpath/

Dyld поддерживает текущий стек путей, называемый списком путей выполнения.Когда встречается @rpath, он заменяется каждым путем в списке путей выполнения до загружаемого dylib, если он найден.Стек пути выполнения создается из команд загрузки LC_RPATH вцепочка зависимостей, приводящая к текущей нагрузке на dylib. Вы можете добавить команду LC_RPATH load к изображению с опцией -rpath до ld (1). Вы даже можете добавить LC_RPATH путь команды загрузки, который начинается с @loader_path/, и это приведет к запуску пути стек путей относительно изображения, содержащего LC_RPATH. Использование @rpath наиболее полезно, когда у вас есть комплекс структура каталогов программ и дилибов, которые можно установить где угодно, но сохраняйте свои относительные позиции. Этот сценарий может быть реализован с использованием @loader_path, но каждый клиент Dylib может потребоваться другой путь загрузки, потому что его относительный Положение в файловой системе отличается. Использование @rpath вводит уровень косвенности, который упрощает вещи. Вы выберите местоположение в вашей структуре каталогов в качестве точки привязки. Каждый dylib получает путь установки, который начинается с @rpath и путь к dylib относительно точки привязки. Каждый главный исполняемый файл связан с -rpath @loader_path/zzz, где zzz путь от исполняемого файла до точки привязки. Во время выполнения dyld устанавливает путь выполнения в качестве точки привязки, тогда каждый dylib найдено относительно точки привязки.

...