Skip to content

GNUstep install with clang, blocks, and Grand Central Dispatch (GCD)

June 3, 2013

Grand Central Dispatch is an Apple  technology to assist building and running apps on multi-core processors. The library for Grand Central Dispatch is called libdispatch, and tasks can be submitted to libdispatch with blocks, or with a C API.

Here is a record of my installation of GNUstep-base with clang, blocks and Grand Central Dispatch (GCD) on Linux.

GNUstep runtime – libobjc2

The runtime library for Objective C code started out as libobjc until Apple released Objective C version 2, when it became libobjc2. You can get the background here: http://wiki.gnustep.org/index.php/ObjC2_FAQ .

For Objective C version 2 support you have a choice, in that you can use either a recent GCC, or clang. However, keep in mind that GCC at time of writing doesn’t support blocks. So while libobjc2 can be compiled with gcc (since the blocks runtime in libobjc2 doesn’t use blocks), you must compile your own code with clang.  Nevertheless, it is recommended to build libobjc2 with a recent clang.

Apart from blocks, the runtime should support the same features irrespective of  what compiler it is built with.

As you may know GNUstep-base provides block support, irrespective of compiler support for blocks. However in practice, I’m told that GNUstep-base should be built with clang for use with blocks (David Chisnall of GNUstep advises the GNUstep developers made an effort to avoid this, but it might not quite work, and in particular the subclassing of NSRegularExpression won’t work correctly if GNUstep is not built with blocks support).

Also, I found that at the moment (June 2013), libdispatch requires clang to build it.

So one thing is clear, with a stated goal of running GNUstep with blocks and libdispatch, we’re going to need a libobjc2 compiled with clang.

Distributions

I tend to use Debian server side so I had a look at the packages available. It turns out that Debian wheezy and Ubuntu 13 build libobjc2 and libdispatch with clang, while GNUstep packages are still built with gcc.

And if your flavour is FreeBSD, FreeBSD and PCBSD also build libobjc2 and libdispatch with clang, and GNUstep with gcc.

If you do install libdispatch on any of these systems you’ll see a package called cblocksruntime is installed also. What is cblocksruntime? It is an implementation of C blocks to enable compilation and running of libdispatch without the need for libobjc2. Now the way libblocksruntime is built, it will defer to libobjc2 if libobjc2 is linked. So in fact, we’re fine to have libobjc2 and libblocksruntime installed on the same system and if this is the case, the blocks support in libobjc2 will take precedence over that in cblocksruntime.

First attempt…

Observing that libobjc2 and libdispatch are built with clang while gnustep-base is built with GCC, I wasn’t sure if everyone would get along fine or if it was going to turn into a family squabble. It turned out to be a bit of both.

It turns out that that the objc.h header which is included in Foundation.h should come from libobjc2. In fact, as it stands right now, Debian and Ubuntu provide objc.h from GCC (Note: FreeBSD 9.x and PCBSD will be fine here unless you install GCC from ports). So once I started writing code on Ubuntu, I had to install GCC and put the location of objc.h in <GNUstep root>/Makefiles/config.make. At the same time I was trying to find my way with GNUstep and I ran into other issues. In addition, posts to the gnustep-discuss newsgroup this year consistently recommended installing from source, so to the the source I went.

The rest of this post will describe how to do a complete installation from source of clang, libobjc2, gnustep-base, and libdispatch.

I’ve since found that there is another way – isn’t there always. My understanding is that one can use clang as shipped on Debian or FreeBSD, to compile libobjc2 and gnustep-base, and the existing libdispatch will play nicely. If you do this, David Chisnall provides the following comments,

  • The objc.h header should be provided by libobjc2.  If you’re installing on Linux and don’t have GNUstep installed, then you may have problems because the default install location for the headers will be in /usr/local/include/objc, which won’t be in your search path.  Changing the prefix to /usr/ (from /usr/local) should fix this.
  • On FreeBSD / PC-BSD, you can just install the libdispatch port and add -ldispatch to your linker flags.  This version works out of the box with GNUstep (and doesn’t have any GNUstep-specific patches applied, so others from the same upstream should as well).
  •  It is completely safe to compile and link libdispatch against LLVM’s libBlocksRuntime and then link your code against libobjc2.  The weak symbols in libBlocksRuntime will be ignored in preference to the ones in libobjc2.

libobjc2 and gnustep-base installation

I installed and compiled clang, libobjc2, and gnustep-base on each of Gentoo, Kubuntu 13. Here is a look at each platform.

Gentoo

Gentoo takes a while to build the OS initially, but was the simplest to get everything working. It was pretty much just a case of setting some use flags and then choosing all the packages I wanted. The only additional step was a perusal of the clang howto, and I chose to stay with gcc for the system, and use clang for all the GNUstep related builds. (see http://wiki.gentoo.org/wiki/Clang)

See the end of this post for the Gentoo configuration files I used.

Kubuntu

I recommend a fresh Debian or Ubuntu installation. If not, remove all gnustep packages, libobjc* packages, libdispatch* packages, and libblocksruntime* packages.

Ivan Vucica has a handy install script for download: https://bitbucket.org/ivucica/gnustep-ubuntu/src .  As well as the packages referenced in the script, you will also need cmake; which you should install now. Re Ivan’s script, here are a couple of things:-

  • kubuntu 13 does not have the openssl-dev package so left it out
  • libobjc2 now requires cmake instead of GNU make. Check out the install instructions in the file INSTALL inside the libobjc2 source and build accordingly. When you run “cmake ..”, look at the output and make sure that
    C compiler is clang, and,
    CXX compiler is clang++

PCBSD 9.1

I had a look at PCBSD because it is based on FreeBSD, and of course OS X is derived from FreeBSD. As a result, libdispatch on FreeBSD and PCBSD uses the kernel interfaces for event dispatch directly, it doesn’t need an emulation wrapper.

I haven’t run PCBSD before and was impressed. PCBSD has a nifty feature called the warden to manage containers implementing a ports jail. I used the warden to set up a container with its own IP address, and a set of FreeBSD packages implementing GNUstep and libdispatch. This package container is completely independant of packages in the main PCBSD package repository, and I can see that you could set up a developer container and a test-deployment container on the same system. Such a setup is way simpler and uses less machine resource than maintaining two separate virtual machines to do the equivalent.

It turned out that the software stack of  libobjc2, gnustep-base, and libdispatch was implemented in a similar way on FreeBSD as on Debian. Namely, libobjc2 and libdispatch compiled with clang, and GNUstep libraries and applications compiled with GCC. By the way, a change of compiler to clang, for all the GNUstep software is imminent. This post describes the install of GNUstep, blocks and GCD on PCBSD 9.1

Try it out… GNUstep code with Blocks

Being new to GNUstep, I quickly learnt the importance of the GNUstep.sh script. GNUstep.sh sets up a number of environment variables which are absolutely necessary to compile and run GNUstep code. On Gentoo in a bash shell run

“. /usr/share/GNUstep/Makefiles/GNUstep.sh”, and put this line in your profile at startup by adding it to ~/.bashrc . That done you’re ready for the code below.

Note: On *BSD, GNUstep.sh is under /usr/local rather than /usr.

Below is a sample program with blocks called source.m, and a make file called GNUmakefile. Put the two files “source.m” and “GNUmakefile” in the same directory and type “gmake” or “make” (whichever calls “GNU make” on your system). You should then see a directory appear called “obj” and in it should be the program “blocks” which you can run.

Program: source.m

#include

int main (int argc, char ** argv) {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSDate *date = [NSDate date];
 NSLog(@"Begin: The date and time is %@", date);

void (^now)(void) = ^ {
 NSLog(@"Block: The date and time is %@", date);
 };

sleep(5);
 date = [NSDate date];
 NSLog(@"After delay: The date and time is %@", date);
 now();

[pool release];
 return 1;
}

makefile: GNUmakefile

include $(GNUSTEP_MAKEFILES)/common.make

ADDITIONAL_OBJCFLAGS += -fblocks -fobjc-runtime=gnustep-1.7
TOOL_NAME = blocks
blocks_OBJC_FILES = source.m

include $(GNUSTEP_MAKEFILES)/tool.make

Output:

Begin: The date and time is 2013-06-04 09:19:39 +1200
After delay: The date and time is 2013-06-04 09:19:44 +1200
Block: The date and time is 2013-06-04 09:19:39 +1200

Blocks and Grand Central Dispatch

Here is some background on GCD and blocks

  • GCD: As far as I can make out, there are two source repositories for an implementation of GCD on Linux. One by [https://www.heily.com/trac/libdispatch/ Mark Heily] and one called [http://opensource.mlba-team.de/xdispatch/docs/current/index.html libxdispatch]. So far as using GCD with GNUstep, Mark’s library is the one to use, and this is also the libdispatch library in Debian and Ubuntu.
  • A Grand Central Dispatch implementation requires libpthread and libkqueue.
  • libpthread is the POSIX threading library. There are some non-standard extensions for allowing the kernel to manage work queues based on system load, but on non-Apple platforms they’re just emulated in userspace (unless you apply Stacy Son’s patches to FreeBSD).
  • libkqueue is a userspace implementation of BSD’s kqueue() kernel event notification mechanism. On Linux for instance, libkqueue translates epoll, inotify, signalfd, and timderfd, to the kevent structure.
  • Blocks: Using blocks with GCD will often result in simpler and more elegant code, but blocks are not part of standard C. GNUstep implements exactly the same ABI for blocks as Apple / LLVM’s libBlocksRuntime, it just implements the integration between blocks and the Objective-C runtime differently.  It is completely safe to compile and link libdispatch against LLVM’s libBlocksRuntime and then link your code against libobjc2.  The weak symbols in libBlocksRuntime will be ignored in preference to the ones in libobjc2.

To install libdispatch I used a repository from Nick Hutchinson which in turn is based on the library of Mark Heily. I used Nick’s repository because it has recent patches while Mark’s hasn’t been updated for a while.

Download each of:

The installs for libpthread and libkqueue are gnustep-make builds so check you have GNUstep environment variables in your current shell (“export  | grep GNU” in a bash shell).

Check the INSTALL files, but as I remember for libpthread_workqueue and libkqueue, installation just involved:-

./configure
make install

Each library also has a test created either in the top level directory or in the tests directory. Run the tests. You may need to “make check” to build/run the test.

And compile and install libdispatch. libdispatch has a separate build style than the others:

sh autogen.sh
./configure
make
make install

I got the following error on Gentoo Linux, when running configure

checking for sys/event.h... no

checking for KQUEUE... configure: error: Package requirements (libkqueue) were n

Package libkqueue was not found in the pkg-config search path.
Perhaps you should add the directory containing `libkqueue.pc'
to the PKG_CONFIG_PATH environment variable

Fixed with:

mv /usr/local/lib64/pkgconfig/libkqueue.pc \
  /usr/share/pkgconfig/

And the next problem was related to the i18n library which has “block” declared in the header like so…

/usr/include/unistd.h - line 1149
extern void encrypt (char *__block, \
   int __edflag) __THROW __nonnull ((1));

I commented out line 1149 to get the compile completed, and then uncommented afterwards.

And at the end of all of this a nice new libdispatch library.

Time to try it out. Below is the source for a simple program to call Grand Central Dispatch, along with a GNUMakefile.

#include
#include

int main (int argc, char ** argv)
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 dispatch_async(myQueue, ^{
 printf("this is a dispatch block!\n");
 });
 dispatch_async(myQueue, ^{
 printf("this is another dispatch block!\n");
 });
 sleep(1);
 [pool release];
 return 1;
}

GNUmakefile:

include $(GNUSTEP_MAKEFILES)/common.make

TOOL_NAME = gcdtest

gcdtest_LIBRARIES_DEPEND_UPON += -ldispatch -lkqueue -lpthread_workqueue

gcdtest_OBJC_FILES += source.m

# Additional library directories the linker should search
ADDITIONAL_LIB_DIRS += -L/usr/local/lib64
# Additional TOOL libraries to link
ADDITIONAL_TOOL_LIBS += -ldispatch -lkqueue -lpthread_workqueue

include $(GNUSTEP_MAKEFILES)/tool.make

One last thing – memory management

If you’ve built GNUstep with clang as described above, i.e. a version of clang supporting blocks, as on Debian or later, you have choices for memory management as on OS X:-

  • Traditional autorelease pools
  • ARC and autorelease pool blocks (autoreleasepool{})
  • Garbage Collection. Keeping in mind that garbage collection has been deprecated in OS X as of 10.8. If you wish to implement garbage collection, compile with boehm-gc as per this wiki article. http://wiki.gnustep.org/index.php/Building_GNUstep_with_Clang

Credits: David Chisnall for a lot of input into this post to ensure technical accuracy

Any errors remaining are of course all mine.

————————————————————-

Funtoo/Gentoo config files below

$ cat /etc/portage/env/clang
CC=clang
CXX=clang++

CFLAGS="-march=core2 -O2 -pipe "
#CFLAGS="-march=core2 -O2 -pipe -fblocks "
#CFLAGS="-march=core2 -O2 -pipe -pthread -fblocks"

# from clang on funtoo docs http://www.funtoo.org/wiki/Clang
#CFLAGS="-O2 -march=native -mtune=native -pipe"
#CXXFLAGS="-O2 -march=native -mtune=native -pipe"
#LDFLAGS="-Wl,--as-needed"

$ cat /etc/portage/package.env
gnustep-base/libobjc2 clang
dev-libs/libatomic_ops clang
dev-libs/nettle clang
gnustep-base/gnustep-make clang
dev-libs/libtasn1 clang
net-libs/gnutls clang
gnustep-base/gnustep-base clang
app-arch/libarchive clang
dev-util/cmake clang
dev-libs/compiler-rt clang
gnustep-base/gnustep-gui clang
gnustep-base/gnustep-back-cairo clang
virtual/gnustep-back clang
gnustep-apps/projectcenter clang
# email
gnustep-apps/gnumail clang
gnustep-apps/addresses clang
gnustep-libs/pantomime clang

$ cat /etc/portage/make.conf
CFLAGS="-march=core2 -O2 -pipe"
CXXFLAGS="-march=core2 -O2 -pipe"
USE="-minimal libobjc2 ldap native-exceptions jpeg libnotify lock session startup-notification svg thunar "$ eselect profile listCurrently available arch profiles:
 [1] funtoo/1.0/linux-gnu/arch/x86-64bit *
 [2] funtoo/1.0/linux-gnu/arch/x86-64bit/pure64
Currently available build profiles:
 [3] funtoo/1.0/linux-gnu/build/stable
 [4] funtoo/1.0/linux-gnu/build/current *
 [5] funtoo/1.0/linux-gnu/build/experimental
Currently available flavor profiles:
 [6] funtoo/1.0/linux-gnu/flavor/minimal
 [7] funtoo/1.0/linux-gnu/flavor/core *
 [8] funtoo/1.0/linux-gnu/flavor/desktop
 [9] funtoo/1.0/linux-gnu/flavor/workstation
Currently available mix-ins profiles:
 [10] funtoo/1.0/linux-gnu/mix-ins/audio
 [11] funtoo/1.0/linux-gnu/mix-ins/console-extras
 [12] funtoo/1.0/linux-gnu/mix-ins/dvd
 [13] funtoo/1.0/linux-gnu/mix-ins/gnome
 [14] funtoo/1.0/linux-gnu/mix-ins/kde *
 [15] funtoo/1.0/linux-gnu/mix-ins/mate
 [16] funtoo/1.0/linux-gnu/mix-ins/media
 [17] funtoo/1.0/linux-gnu/mix-ins/print
 [18] funtoo/1.0/linux-gnu/mix-ins/python3-only
 [19] funtoo/1.0/linux-gnu/mix-ins/rhel5-compat
 [20] funtoo/1.0/linux-gnu/mix-ins/server-db
 [21] funtoo/1.0/linux-gnu/mix-ins/server-mail
 [22] funtoo/1.0/linux-gnu/mix-ins/server-web
 [23] funtoo/1.0/linux-gnu/mix-ins/X *
 [24] funtoo/1.0/linux-gnu/mix-ins/xfce
 [25] funtoo/1.0/linux-gnu/mix-ins/vmware-guest
About these ads

From → GNUstep

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: