blocksruntime

The libBlocksRuntime.a library from compiler-rt.
Table of Contents
Overview
Why?
License
Install
Download
Do I Need This?
GNU C Library (glibc) Problem
Blocks Language Extension
See Also
Git Repository Browser

A clone of the compiler-rt library (http://compiler-rt.llvm.org/) but only the BlocksRuntime library portion. (Actually the compiler-rt master subversion source repository at http://llvm.org/svn/llvm-project/compiler-rt has an automatic git mirror at http://llvm.org/git/compiler-rt.git the refs/heads/master of which is cloned into refs/heads/compiler-rt of this repository.)

In addition to the clone of the BlocksRuntime library sources, a config.h file, testprefix.h file, a sample.c file and a few convenient shell scripts have been added in order to build, test and install the Block.h header and libBlocksRuntime.a library without needing cmake or make.

Any system which has a version of the clang compiler (either pre-installed or installable via any mechanism) with support for the -fblocks option should be supported.

In particular, the FreeBSD, Linux, MacPorts and mingw versions of clang are known to work with the blocks runtime. Your system may already come with the BlocksRuntime library pre-installed or installed as part of the clang package. And furthermore, it may not require linking with any special library to use it either. See the Do I Need This? section for a way to check.

Why?

You want to use the Blocks language extension, but when you attempt to build a test program with something like:

clang -o sample -fblocks sample.c
you get a linker error something about an undefined __NSConcreteGlobalBlock symbol so you try:
clang -o sample -fblocks sample.c -lBlocksRuntime
but then you get a linker error about ld: library not found for -lBlocksRuntime instead. This repository can help you build the libBlocksRuntime.a library very easily so that you can successfully use the Blocks language extension supported by the -fblocks option of the clang compiler.

See the README.txt file for further information.

License

Dual licensed under both the University of Illinois "BSD-Like" license and the MIT license. See here, here and the LICENSE.TXT file for further information.

Install

See the README.txt file for further information and be sure to read the section on a glibc header incompatibility if using glibc.

Download

You can download this project in either tar or zip formats.

You can also clone the project with Git by running:

git clone git://github.com/mackyle/blocksruntime

This project also has a mirror on repo.or.cz which has a much better graphic log browser for the project.

Do I Need This?

Here's a checklist to help you decide whether or not you need this library.

  1. Do you have the clang compiler? Try this:
    clang --version
    If it says something like clang: command not found then you do not have the clang compiler so you have no need for this library.
  2. Does your version of clang support -fblocks? Try this:
    echo "void (^b)(void) = ^{};" |
    clang -c -o /dev/null -fblocks -x c -
    If you get any kind of error output then your version of clang does not support the -fblocks option so you have no need for this library.
  3. Does your clang installation already include built-in libBlocksRuntime.a support? Try this:
    echo "int main(){return ^{return 42;}();}" |
    clang -o /dev/null -fblocks -x c -
    If you do NOT get any kind of error output then your installation of clang already includes the Blocks runtime support and you have no need for this library.
  4. Does your clang installation already include a separate BlocksRuntime library? Try this:
    echo "int main(){return ^{return 42;}();}" |
    clang -o /dev/null -fblocks -x c - -lBlocksRuntime
    If you do NOT get any kind of error output then your installation of clang already provides the Blocks runtime support via the -lBlocksRuntime library option and you have no need for this library (which provides the same thing).
  5. If you got to this step then yes, you do need this library if you want to use the Blocks support available with your installation of the clang compiler.

GNU C Library (glibc) Problem

This issue is typically seen on Linux systems that use glibc. The glibc source contains a posix/unistd.h header file which typically ends up installed as /usr/include/unistd.h and contains this declaration:

extern void encrypt (char *__block, int __edflag) __THROW __nonnull ((1));
Unfortunately when compiling with the -fblocks option __block cannot be used as a formal parameter name.

If the source file being compiled needs to use the -fblocks option and also #include <unistd.h> from glibc then there are two options:

  1. Change the formal parameter name in the /usr/include/unistd.h header from __block to something else such as __blockdata (or anything else so long as it’s not __block)
  2. Use the workaround from the testprefix.h header file which temporarily undefines __block includes the unistd.h header and then redefines __block:
    #ifdef __linux__
    #undef __block
    #endif
    #include <unistd.h>
    #ifdef __linux__
    #define __block __attribute__((__blocks__(byref)))
    #endif
    
    Note that this example tests the __linux__ preprocessor macro, but that is not necessarily a reliable check for the problem since glibc could be in use without __linux__ being defined although in practice this seems to work fine.

Blocks Language Extension

Various Blocks language extension documentation can be found at: Basically the Blocks language extension adds closure support to the C/Objective-C/C++/Objective-C++ languages. If you are familiar with the Smalltalk programming language, the Blocks language extensions provides something very similar to Smalltalk code blocks. Here's the sample.c file from this repository:
/*
   Test your installation by running:

     clang -o sample -fblocks sample.c -lBlocksRuntime && ./sample

   The above line should result in:

     Hello world 2

   If you have everything correctly installed.
*/

#ifndef __BLOCKS__
#error must be compiled with -fblocks option enabled
#endif

#include <stdio.h>
#include <Block.h>

int main()
{
  __block int i;
  i = 0;
  void (^block)() = ^{
    printf("Hello world %d\n", i);
  };
  ++i;
  void (^block2)() = Block_copy(block);
  ++i;
  block2();
  Block_release(block2);
  return 0;
}
In the above sample code, both block and block2 are block variables. And while i is an integer variable, the optional __block storage class language extension modifies i's behavior when it's accessed from within a block.

See Also

Git Repository Browser

Repository browsers are available at: