Objective-C blocks with a static runtime on Windows


At this moment it is not possible to use blocks when linking to a static Objective-C runtime on Windows due to a patch applied in r271138 (http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160523/160244.html).

The idea of the patch appears to enforce dynamic linking with NSConcreteStackBlock, but this only results in an undefined reference to `__imp__NSConcreteStackBlock’ when linking statically (with e.g. objfw).

There is a TODO in the added code, however, how can it be called a todo, when the added hack simply breaks block support when linking to static runtimes? It worked just fine before.

From what I understand the issue for no static block support is due to detection issues: there seems to be no obvious way to detect the runtime type until the linking step.

Will it be ok to add an extra argument (e.g. -fblock-static-runtime) to disable the hacked code? Or could there be any other solution?


I think that having a flag is fine. We already have a link time flag for static libc++/libc. Pulling that into the compile time and adding a flag for the blocks runtime seems reasonable to me.

However, it’s for user code that static blocks runtime would be more challenging to support. For the runtime itself, it’s actually a matter of ensuring that you have the right DLL storage annotations.

extern __declspec(dllexport) long _NSConcreteStackBlock;
void f(void) {
__block int i;
void (^b)() = ^{ ++i; };

That seems to compile properly on trunk and not give you import storage on _NSConcreteStackBlock.

Thank you for pointing this out.
That is a pretty interesting workaround and it actually seems to work, although the idea itself feels reasonably unobvious.
For the existing compilers it is probably ok to use, but having a flag in the future will likely be saner.
Still, it probably needs to be discussed with objfw staff form now on.