如何在Xcode 4中使用dylib文件创建工作框架

我在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来编译头文件public。 项目构建没有问题,但在框架中没有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文件?


我认为你误解了错误信息。

.framework作为动态库工作,但在.framework文件夹内不会有任何带有实际.dylib文件扩展名的Mach-O可加载对象文件。

有几个原因可能会在运行时从dyld (动态链接库加载器)中获取该错误消息。 首先是你忘记在构建过程中将.frameworks复制到构建的应用程序包中。 虽然可以将它们复制到应用程序包内的任何位置,但传统位置在AppName.app/Contents/Frameworks/中。 如果您还没有这样做,请选择“项目”>“新建构建阶段”>“新建文件构建阶段”。 将目标弹出框更改为框架,如下图所示。

在这里输入图像描述

然后将框架图标拖到文件夹中,以便在构建过程中将其复制。

在这里输入图像描述

在运行时无法找到框架的第二个也是更可能的原因是,您没有为主要可执行文件指定任何运行路径搜索路径。 (这是必须的,因为正如我们从错误消息中看到的那样,您的框架是使用更新的@rpath/ style安装名称( @rpath/add.framework/Versions/A/add )而不是旧的@executable_path/@loader_path/ styles)。

假设您将自定义框架复制到上述位置,您可以添加@loader_path/../Frameworks的运行路径搜索路径条目,如下图所示:

在这里输入图像描述

以下摘录解释了在运行时如何找到动态库来自dyld的联机帮助页面:

动态库加载

与许多其他操作系统不同,达尔文没有通过它们的叶文件名来定位相关的动态库。 而是使用每个dylib的完整路径(例如/usr/lib/libSystem.B.dylib )。 但有时候完整路径不合适; 例如,可能希望您的二进制文件可以安装在磁盘上的任何位置。 为了支持这一点,有三个@xxx/变量可以用作路径前缀。 在运行时, dyld@xxx/前缀替代动态生成的路径。

@executable_path/

该变量将替换为包含进程主要可执行文件的目录的路径。 这对于加载嵌入到.app目录中的dylib /框架非常有用。 如果主要可执行文件位于/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/

该变量被替换为包含使用@loader_path包含加载命令的mach-o二进制文件的目录的路径。 因此,在每个二进制文件中, @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/FooMyfilter.plugin目录可以围绕在文件系统中移动,并且dyld仍然会能够加载嵌入式框架。

@rpath/

Dyld维护一个称为运行路径列表的路径的当前堆栈。 遇到@rpath时,它将被运行路径列表中的每个路径替换,直到找到可加载的dylib。 运行路径堆栈是根据导致当前dylib加载的LC_RPATH链中的LC_RPATH加载命令构建的。 可以添加一个LC_RPATH到图像加载命令与-rpath选项ld (1)。 您甚至可以添加以@loader_path/开头的LC_RPATH加载命令路径,并且它将在运行路径堆栈上推送相对于包含LC_RPATH的映像的LC_RPATH 。 当你有一个复杂的程序和dylibs目录结构时, @rpath的使用是非常有用的,它可以被安装在任何地方,但保持它们的相对位置。 这个场景可以使用@loader_path来实现,但是dylib的每个客户端可能需要不同的加载路径,因为它在文件系统中的相对位置是不同的。 @rpath的使用引入了简化事物的间接级别。 您在目录结构中选择一个位置作为定位点。 每个dylib都会得到一个以@rpath开头的安装路径,并且是dylib相对于定位点的路径。 每个主要可执行文件都与-rpath @loader_path/zzz ,其中zzz是从可执行文件到定位点的路径。 在运行时, dyld将其运行路径设置为定位点,然后每个dylib都相对于定位点找到。

链接地址: http://www.djcxy.com/p/76411.html

上一篇: How do I create a working framework with dylib files in Xcode 4

下一篇: Generating a static library