Support GNUstep blocks runtime #2

Open
LubosD opened this Issue Dec 18, 2012 · 10 comments

Projects

None yet

3 participants

@LubosD
LubosD commented Dec 18, 2012

Hi,

GNUstep's libobjc2 runtime provides blocks support as well. It would be nice if this worked with your tree out of box. This is what I need to do to get things working:

LIBS="-l:libobjc.so.4" CFLAGS="-D__BLOCKS__ -O2 -fblocks" ./configure

(-D__BLOCKS__ may not be needed, I added that just to be sure).

then you need to replace

#include <Block_private.h>
#include <Block.h>

with this:

#include <objc/blocks_runtime.h>
#include <objc/blocks_private.h>

Given that libdispatch is most likely to be used by cross-platform apps, it is very likely that it's users will have GNUstep installed when on Linux.

@nickhutchinson
Owner

Hi Lubos,

I'm not familiar with GNUStep, and I'm not even terribly familiar with the Autotools build system that libdispatch uses, but I should have time to look into this in a few weeks.

In the meantime, you're welcome to submit a pull request.

Cheers,
Nick

@LubosD
LubosD commented Dec 22, 2012

Yeah, I hate Autotools too :-( Never really managed to do anything useful with it.

@xcvista
xcvista commented May 19, 2013

You could include a script that will make symlinks to "pose" GNUstep libobjc2 as libBlockRuntime as well as required header files. I will fork this project to do all the needed changes. This will break the requirement of libBlocksRuntime (or clang's compiler-rt) but add requirements of GNUstep-make and GNUstep's libobjc2.

@nickhutchinson
Owner

It'd be easy enough to extend the FindCBlocks CMake module to look for GNUStep's runtime, and also make the choice of blocks runtime configurable. (Not quite sure how to do this with Automake, but I should bite the bullet and learn how...)

Do you know why the GNUstep guys chose different header names? I think it'd be cleaner to symlink them to Block.h & Block_private.h as part of the build process.

Finally, why do you prefer GNUstep's blocks implementation to libBlocksRuntime in the first place?

On 19 May 2013, at 19:50, Maxthon Chan notifications@github.com wrote:

You could include a script that will make symlinks to "pose" GNUstep libobjc2 as libBlockRuntime as well as required header files. I will fork this project to do all the needed changes. This will break the requirement of libBlocksRuntime (or clang's compiler-rt) but add requirements of GNUstep-make and GNUstep's libobjc2.


Reply to this email directly or view it on GitHub.

@xcvista
xcvista commented May 20, 2013

Well because the blocks ABI is a bit different between GNUstep and Apple.

Apple used their C-level CoreFoundation technologies to implement blocks but GNUstep used GSBlock, an Objective-C class.

Simpler cross-use the ABI is okay, but when any copying is involved, the difference in ABI will break the program and corrupt memory structure.

@nickhutchinson
Owner

Ah okay, that's interesting. Is this ABI difference documented anywhere?

@xcvista
xcvista commented May 22, 2013

I have no idea, but I know the API is identical. So pretty much it is link-against thing. Just drop the libBlocksRuntime header files and library and use libobjc2 ones.

@LubosD
LubosD commented Jun 24, 2013

The ABI of GNUstep's Blocks should be identical to Apple's Blocks. I don't know why they chose different header file names, but now that you've switched to CMake, it should be much easier to support it.

See https://github.com/LubosD/darling-overlay/blob/master/dev-libs/libdispatch/files/gnustep-blocks.patch for the patch I currently use.

@xcvista
xcvista commented Jun 24, 2013

I just drop 3 symlinks (target path relative to source location):

$PREFIX/include/objc/block_runtime.h -> Blocks.h
$PREFIX/include/objc/block_private.h -> Blocks_private.h
$PREFIX/lib/libobjc.so -> libBlocksRuntime.so

and when building anything that is asking for blocks runtime add -I$PREFIX/include/objc. Alternatively, drop 4 symlinks and no further changes is needed:

$PREFIX/include/objc/block_runtime.h -> ../Blocks.h
$PREFIX/include/objc/block_private.h -> ../Blocks_private.h
$PREFIX/include/objc/Availability.h -> ../Availability.h
$PREFIX/lib/libobjc.so -> libBlocksRuntime.so

On Jun 24, 2013, at 20:37, Luboš Doležel notifications@github.com wrote:

The ABI of GNUstep's Blocks should be identical to Apple's Blocks. I don't know why they chose different header file names, but now that you've switched to CMake, it should be much easier to support it.

See https://github.com/LubosD/darling-overlay/blob/master/dev-libs/libdispatch/files/gnustep-blocks.patch for the patch I currently use.


Reply to this email directly or view it on GitHub.

@LubosD
LubosD commented May 11, 2014

So I think the best way forward is to use the same approach as GNUstep: weak linking.

  1. Copy the needed Blocks header files or just declarations into your project. Add __attribute__((weak)) to all function declarations. You may want to use some macros so that you don't apply this attribute on Windows, where weak linking is not possible.
  2. Forget about libBlocksRuntime or any other runtime, do not include any external header files for Blocks.
  3. Do not link to any specific Blocks runtime.
  4. Everything will work nicely.

Explanation - there are only two situations possible:

  • The user of your library doesn't use blocks in his code. Therefore he doesn't use any of the block-accepting functions within libdispatch. Hence the weak references (being NULL at this time) are never used. The user is also not forced to install any Blocks runtime.
  • The user of your library uses blocks. Because of that he links to some kind of Blocks runtime and weak refs within libdispatch point to symbols in that runtime. The user is not forced to use any specific runtime.
This was referenced Mar 15, 2015
@nickhutchinson nickhutchinson added this to the 0.2 milestone Mar 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment