Chapter 31. GNUstep

Developers often ask me if their Cocoa code can be used on other platforms. My answer is usually, “Well ... eh ... not really.” This chapter gives a longer answer to that question.

When NeXT made the OpenStep API (which was later renamed Cocoa) be an open standard, the Free Software Foundation announced that it would provide an open-source implementation of the standard. That was a decade ago, and the group has yet to release a 1.0 version of this implementation called GNUstep (http://www.gnustep.org).

GNUstep comprises replacements for Xcode, Interface Builder, and the Cocoa framework. There are also subprojects to create frameworks for Web development and database access. GNUstep should run on all sorts of Unix machines and even Windows, but I've used it only on Linux.

The effort may be a noble one, but using GNUstep is not for the faint of heart:

  • GNUstep is difficult to install.

  • The tools are buggy and crash regularly.

  • Porting your application from Mac OS X is difficult because the file formats for nib files are different under GNUstep. (While the OpenStep API is open, Apple has kept the nib file format closed and proprietary.)

  • The interface that GNUstep creates is a decent copy of the NeXT UI. It was a slick look in 1994, but now the look and feel are like neither the Mac nor a normal X11 application.

  • Quartz and the Apple Window Server run natively on Mac OS X. GNUstep attempts to graft this graphics model onto whatever back end it is using. (On most systems, X11 serves as the back end.) The performance and aesthetics may disappoint users who are familiar with Mac OS X.

If after reading these warnings you still feel smart enough and determined enough to install and use GNUstep, I'll do my best to show you how to get started.

Creating a System That Will Run GNUstep Applications

Start with a nice, fresh Linux machine. The GNUstep team tends to be fairly aggressive about using the latest gcc, so you'll want to make sure the machine is up-to-date with a recent distribution. Install WindowMaker (http://www.windowmaker.org) as your window manager—the package management system on your machine should make this easy. (Any window manager will work, but the NeXT-style menus and icons look a lot better with WindowMaker.)

You'll also want to download and install ffcall. It is available via anonymous FTP at ftp.gnustep.org.

The easiest way to install GNUstep is to use CVS from the terminal. Log in to the server (just press Enter when asked for a password) and download the entire project:

% cvs -d:pserver:[email protected]:/cvsroot/gnustep login
% cvs -z3 -d:pserver:[email protected]:/cvsroot/gnustep co gnustep

This will create a directory named gnustep. Inside this directory, you will find a directory called core that has four important parts:

  1. makeAll of the makefiles needed to build GNUstep applications. It also includes a script called GNUstep.sh, which gives you all of the necessary environment variables. By default, it is installed in /usr/GNUstep/System/Library/Makefiles/.

  2. baseThe replacement for Foundation.framework.

  3. guiThe replacement for Appkit.framework.

  4. backTo make it possible to port the AppKit to several different platforms, the system-specific parts have been moved into a carefully delineated back-end, called back.

There is also a script in the core directory called compile-all. This handy script will configure, build, and install the entire core for you. The system, for portability reasons, does not use frameworks. The libraries and headers will be installed in /usr/GNUstep/System.

With the libraries and makefiles installed, you next need to start up some daemons. The gdomap daemon owns port 538 and tracks services that your GNUstep applications create. The gdnc daemon holds the distributed notification center. You should start both when your machine boots:

# Setup for the GNUstep environment
if [ -f /usr/GNUstep/System/Makefiles/GNUstep.sh ]; then
   . /usr/GNUstep/System/Makefiles/GNUstep.sh
fi

# Start the GNUstep daemons
if [ -f $GNUSTEP_SYSTEM_ROOT/Tools/gdomap ]; then
      echo -n "Starting GNUstep services... "
      echo -n "gdomap "
      $GNUSTEP_SYSTEM_ROOT/Tools/gdomap
      echo "gdnc "
      $GNUSTEP_SYSTEM_ROOT/Tools/gdnc
fi

For each user, you will want to set the necessary environment variables. The easiest way to do so is to add the following lines to your /etc/profile:

# Setup for the GNUstep environment
if [ -f /usr/GNUstep/System/Makefiles/GNUstep.sh ]; then
   . /usr/GNUstep/System/Makefiles/GNUstep.sh
fi

You'll want to start the pasteboard server when the X server starts. Create a ~/.xinitrc file:

$GNUSTEP_SYSTEM_ROOT/Tools/gpbs
exec wmaker

At this point, reboot your machine, log in, and start the X server. At a terminal, confirm that the following processes are running:

% ps -auxw | grep GNU
root      1782   15:31   0:00 /usr/GNUstep/System/Tools/gdomap
root      1784   15:31   0:00 /usr/GNUstep/System/Tools/gdnc
aaron     1929   15:37   0:00 /usr/GNUstep/System/Tools/gpbs
aaron     1981   15:38   0:00 grep GNU

Good. If you have gotten this far, you have a system from which you can now run GNUstep applications. You are not, however, ready to develop GNUstep applications.

Building and Starting the Development Tools

In the CVS-created gnustep directory, you will find dev-apps/Gorm. Gorm is the replacement for Interface Builder. At a terminal, issue two commands: make and make install. Gorm will be installed in /usr/GNUstep/System/Applications/Gorm.app.

In dev-apps/ProjectCenter, run make and make install. ProjectCenter is the replacement for Project Builder.

To start ProjectCenter, use WindowMaker's Run... menu item. When the panel appears, type openapp ProjectCenter as shown in Figure 31.1.

Start ProjectCenter

Figure 31.1. Start ProjectCenter

Creating the RandomApp with GNUstep

When ProjectCenter has started, create a new project of type GormApplication. Name it RandomApp, as shown in Figure 31.2.

Create a New Project

Figure 31.2. Create a New Project

Throughout this process, there are a few things to remember:

  • Save often. The tools do crash occasionally.

  • Use the option-key to trigger menu items. For example, option-q will trigger the Quit menu item.

A template project will be created for you. Double-click RandomApp.gorm under the Interfaces group as shown in Figure 31.3.

New Project

Figure 31.3. New Project

Gorm will start and open the RandomApp.gorm file. Drag a button from the palette window onto your window. Change its title to Seed random number generator,as shown in Figure 31.4.

Gorm

Figure 31.4. Gorm

Drop another button on the window. Change its title to Generate random number. Drag a title text field onto the window. Change its string value to ???.

In the Classes page, select NSObject. Create a subclass of NSObject and rename it Foo. Add two actions, generate: and seed:, to the class Foo, as shown in Figure 31.5. Also add an outlet named textField.

Foo

Figure 31.5. Foo

To create the files, use the Create Class Files... menu item in the Classes menu. Save Foo.h and Foo.m in your project directory.

Using the Classes menu, create an instance of Foo.

Control-drag from the seed button to the Foo object. If you are familiar with Interface Builder, you will be surprised that no line appears. (Intellectual property trivia: Apple has a patent on the window-as-a-thin-line technique.) Instead, a green rectangle will appear around the source of the connection (the NSButton) and a purple rectangle will appear around the destination (the Foo). In the list of outlets in the connections inspector, choose target and then choose the action seed:, as shown in Figure 31.6

Making a Connection

Figure 31.6. Making a Connection

Control-drag from the Generate button to Foo and set the action to be generate:. Control-drag from Foo to the text field and set the textField outlet. Save the Gorm file.

In ProjectCenter, edit Foo.m as follows:

#include <AppKit/AppKit.h>
#include "Foo.h" 

@implementation Foo 
- (IBAction)generate:(id)sender 
{
    // Generate a number between 1 and 100 inclusive 
    int generated; 
    generated = (random() % 100) + 1;

    // Ask the text field to change what it is displaying 
    [textField setIntValue:generated]; 
}

- (IBAction)seed:(id)sender 
{
    // Seed the random number generator with the time 
    srandom(time(NULL)); 
    [textField setStringValue:@"Generator seeded"]; 
}

@end

Notice that GNUstep people do not use #import. The implementation of #import in gcc was quite poor until the most recent release. If GNUstep people do not use #import, how do they prevent the same header file from being included more than once? They use the old #ifndef trick in their header files:

#ifndef _MyFramework_H_MyClass
#define _MyFramework_H_MyClass

@class MyClass
...
@end
#endif

Another surprising style difference in GNUstep style is the set of macros that is used quite consistently. A Cocoa programmer typically creates an accessor that looks like this:

- (void)setRex:(NSCalendarDate *)c
{
    [c retain];
    [rex release];
    rex = c;
}

This would work in GNUstep, but GNUstep developers typically use an equivalent macro:

- (void)setRex:(NSCalendarDate *)c
{
    ASSIGN(rex, c);
}

Here are some of the commonly used macros:

  • AUTORELEASE (object)Send an autorelease message to the object.

  • RELEASE (object)Send a release message to the object.

  • RETAIN (object)Send a retain message to the object.

  • DESTROY (variable)Send a release message to the object stored in the variable (often an instance variable), and then set the variable to nil.

  • ASSIGN (variable, value)Assign a value to a variable (often an instance variable). The macro retains the new value, puts the new value in the variable, and then releases the old value. If the variable already had the new value, the macro does nothing.

  • ASSIGN_COPY (variable, value)Same as ASSIGN, but copies the value (instead of retaining it) before assigning it to the variable.

Besides saving a few lines of typing, these macros allow developers to easily substitute the retain count mechanism with automatic garbage collection routines.

Now it is time to build your project. You must make sure that everything is saved: the code, the Gorm file, and the project itself. To see the build panel, click the screwdriver button in ProjectCenter. Click the screwdriver button in the build panel to begin the build, as shown in Figure 31.7.

Building

Figure 31.7. Building

To run your program, click the button with the screen and rocket to get the launch panel. Then click the rocket to run it, as shown in Figure 31.8.

Running

Figure 31.8. Running

Your application should run without a problem. If you click the buttons and nothing happens (or if there are no buttons present), chances are you have forgotten to save something.

That information should suffice to get you started.

The project created in this chapter has a lot of promise, but it is still awkward to use. The frameworks seem further along than the tools, but I wouldn't bet my business on either in their current state. In time, if enough people help, GNUstep will become a great way to run your OpenStep/Cocoa applications on many platforms.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset