Dynamic lookup of weak references

Two scenarios:

a) I am compiling an App which uses a static library which contains a weak reference to a symbol that doesn't exist in the final binary. This is ok because the static library checks if the class is nil before using it (I create the static library). The reference is definitely weak:

// in code
asm(".weak_reference _OBJC_CLASS_$_DDLog");
// resulting static library

$ nm -m AirTurnInterface | grep DDLog
                 (undefined) weak external _OBJC_CLASS_$_DDLog


Ld complains that the symbol does not exist during final link. Surely this should not happen?


b) I produce example code which uses a new Apple API if it exists, again checking if the class is nil. However, even by forcing a weak reference as above, when compiling with Xcode 6 it complains the symbol is missing.


Other than using -undefined dynamic_lookup in the host App, which ignores all undefined symbols weak or otherwise, is there a way to get ld to respect weak references? Maybe I'm missing or misunderstanding something here, this is pretty new to me.

Replies

You need to specify that the symbol is a weak_import not a weak reference.


Trying to do that using .asm() instead of __attribute__((weak_import)) is probably unsupported.

Ok so using __attribute__((weak_import)) instead, I still get the following output:


$ nm -m AirTurnInterface | grep DDLog
                 (undefined) weak external _OBJC_CLASS_$_DDLog


and the linker still complains about the undefined symbol.

Reading the documentation for ld, http://www.manpages.info/macosx/ld.1.html


"When creating a output file with the static link editor when -twolevel_namespace is in effect (now the default) all undefined references must be satisfied at static link time. The flags to allow undefined references, -Usymbol_name, -undefined warning and -undefined sup_press can't be used. When the environment variable MACOSX_DEPLOYMENT_TARGET is set to 10.3 then -undefined dynamic_lookup can also be used."


It seems therefore my only option is to use '-undefined dynamic_lookup', correct? Is there a performance penalty at runtime to using this? Is there no better way?

iOS and OSX use "two level namespace" for symbol binding. That means the static linker records from which dylib each undefined symbol was found. At launch time, the dynamic loader (dyld) uses that info to search for that symbol only in that dylib. The use of weak_import means the symbol might be missing at runtime - but it still must be found at build time (to record the dylib it might be in at runtime). This is different than ELF system were "weak" means the linker won't complain if no definition is found.


You need to give the linker a dylib that defines the symbol, even if that dylib and/or symbol won't be there are runtime.

If I have a static library or a framework but I don't want to ship that with my framework (Client can load it from the internet if they want to use a feature that rely on it), how can I gererate the dylib that defines only its symbols? (Similar to .tdb in Apple's framewors shipped in the iOS SDK)

My app includes some dynamic Frameworks. All of them are loaded by the dlopen function at runtime. However, I found it would be failure at rate of 0.02%.

There are two kindles of errors. The most one shows that `the file does not exist`. Another one shows that `the dlopen function call failed`.

So, my questions are followings:

1. Would dynamic library files or picture files be lost when App downloading from AppStore?

2. Would the missing files affect the installation of App?

3. Which files are necessary to install applications and which ones are not?

4. What could I improve the rate of loading dynamic libraries successful at runtime?