为什么需要-ObjC链接器标志来链接静态库中的类别? (LLVM) [英] Why is the -ObjC linker flag needed to link categories in static libraries? (LLVM)

查看:148
本文介绍了为什么需要-ObjC链接器标志来链接静态库中的类别? (LLVM)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于Apple的技术问答: http: //developer.apple.com/library/mac/#qa/qa1490/_index.html

我认为编译器可以在编译时标记对类别中定义的方法的调用(它知道它们是在类别中定义的,而不是在主类中定义的,因为原型位于@interface Class (Category)部分中)-因此它可以构建外部类别方法"的目标文件中的表格.然后,链接器在进行正常链接后,应该能够连接/合并和处理所有对象的外部类别方法"表,并从所有链接的框架/库/对象中查找匹配类类别中的匹配符号,然后进行链接可以拉入那些尚未落入"目标的物体.

I think the compiler could mark calls to methods defined in categories at compile-time (it knows that they were defined in a category and not the main class because the prototype was in an @interface Class (Category) section) - so it could build a table in the object files of "external category methods". Then the linker, after doing its normal linking, should be able to concatenate/merge and process the "external category methods" tables from all objects and look for matching symbols in matching class categories from all the linked frameworks/libraries/objects, then it can pull in the ones that weren't already 'in' the target.

一定有我想念的东西,但这是什么?为什么这不可能呢?

There must be something I'm missing, but what is it? Why is this not possible?

推荐答案

链接器将静态库视为旧的随机片段大集合,它将从中抽取单个片段来满足来自链接单元其余部分的任何符号请求.

The linker treats static libraries like a big old collection of random pieces from which it will draw individual pieces to fulfill any symbol requests from the rest of the link unit.

即如果主程序调用_foo并且_foo仅出现在静态库中,则_foo以及任何相关的符号将被拖入.

I.e. if the main program calls _foo and _foo only appears in the static library, then _foo, along with any dependent symbols, will be dragged in.

但是,当您调用类别中的方法时,由于Objective-C的动态性,因此没有特定的符号引用.

However, when you call a method in a category, there is no specific symbol reference due to the dynamism of Objective-C.

-ObjC标志告诉链接器,因此,它应该从静态库中获取所有类别,并将它们放入主二进制文件中.

The -ObjC flag tells the linker that, because of this, it should grab all categories from the static library and drop 'em into the main binary.

这有点令人困惑,并且假设编译器对此应该更加聪明(并且可以肯定的是,它应该在开发工具级别提供帮助).重要的是要记住一些事情:

It is a bit confusing and the assumption is that the compiler should be smarter about this (and, assuredly, it should give assistance at the dev tools level). It is important to remember a few things:

  • 链接器滚动时,头文件中声明的所有内容几乎都丢失了.符号是由编译单元而不是头文件创建的.头文件几乎可以保证一个符号将在以后具体创建或由链接实现,但不能在其自身内部创建符号(否则每个编译单元(每个.o都将以的形式结尾)链接时就会出现符号和欢笑.

  • Anything declared in a header file is pretty much lost by the time the linker rolls around. Symbols are created by compilation units, not by header files. Header files pretty much generate a promise that a symbol will be concretely created later or fulfilled by the link, but cannot create a symbol in and of themselves (or else everyone compilation unit -- every .o -- would end up with a copy of the symbol and hilarity would ensue at link time).

Objective-C是完全动态的.当您说[(id)foo bar];时,唯一的要求是bar是在 somewhere 之前定义的.不管它是否真的实现了(无论如何直到运行时).

Objective-C is fully dynamic. When you say [(id)foo bar];, the only requirement is that bar is defined somewhere prior. Doesn't matter if it is actually implemented at all (until runtime anyway).

类别不必具有相应的@implementations;可以使用类别来声明方法可能存在,并且实际上,在将@optional添加到@protocol之前,通常在NSObject(ewwwwww)上使用类别,而没有@implementation表示嘿,此可选方法可能会在运行时存在."

Categories don't have to have corresponding @implementations; a category can be used to declare that methods might exist and, in fact, prior to adding @optional to @protocol, it was common to use a category on NSObject (ewwwwww) with no @implementation to say "Hey, this optional method might exist at runtime".

编译和链接是完全独立的过程.编译是关于扩展代码并将其转换为可执行字节的库.链接就是将这些库放入一个可以实际运行的库中,包括解决库之间的所有依赖关系.编译器实际上并不知道如何链接某些东西,并且链接器也没有任何有关可能定义了哪些东西(不产生硬符号)的信息.

Compilation and linking are completely separate processes. Compilation is all about expanding the code and turning it into libraries of executable bytes. Linking is all about taking those libraries and putting them together into something that can actually be run, including resolving all the dependencies between libraries. The compiler doesn't really know about how something might be linked and the linker doesn't have any information about where things (that didn't yield hard symbols) might have been defined.

最终结果?

链接器没有足够的信息来解决依赖关系.

The linker doesn't have enough information to resolve the dependencies.

这篇关于为什么需要-ObjC链接器标志来链接静态库中的类别? (LLVM)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆