It seems that (best of all, as far as I can tell), Apple's description of weak binding is misleading. I only had success designating the function as weak / weak_import if the definition is really available at the time of the link. This is contrary to the usual behavior of Linux when a loosely coupled character does not need to be detected during communication.
For example, the following compilations on Ubuntu 14.04 with gcc 4.8.2, but not on OS X 10.9.5 with clang
int weakfunc() __attribute__((weak)); int main() { if (weakfunc) return weakfunc(); else return -1; }
The easiest workaround I have found is to explicitly tell the linker to leave this character undefined. For example, clang test.c -Wl,-U,_myfunc . Note that the character name will be different from C and C ++. In C (at least for me, I assume this is consistent), the symbol name has an underscore, as shown here. In C ++, the name is distorted, so you get something like __Z8weakfuncv (not necessarily consistent - I get only one underscore over the changed name in my Ubuntu field).
Following this approach, if a function is defined at run time (for example, through a library preloaded by setting the environment variable DYLD_INSERT_LIBRARIES or if the version of the dependencies in the shared library at run time is different from the time set at build time), the character will be enabled and the function will be summoned at will. If the character is not defined at runtime, then the function is not checked, and we continue to return -1 as desired.
A slightly more complex solution is a link to a dummy library that provides the implementation of the function in question. For example, if you compile the following as libdummy.dylib in the same directory:
int weakfunc() { return 1; }
You can weakly refer to it
clang test.c -weak_library ./libdummy.dylib -flat_namespace
The character is then determined during the link, so the linker is happy and will be marked as loosely coupled in the resulting binary. By linking libdummy.dylib to -weak_library , rather than the standard -l/-L binding, the library dependency itself is weak, so the executable will still work, even if libdummy.dylib is not available at run time.
The -flat_namespace argument tells the linker to use a โflatโ namespace rather than a โtwo-levelโ namespace, which is apparently the default value for OS X. In a two-level namespace, each associated character is tagged with the library from which it came, so without it the linker would only accept the version of weakfunc from the libdummy.dylib library. Please note that in the first case of marking a character as undefined, this character is considered to be from a flat namespace, since the linker has no idea which library it may be in at runtime.