Thursday, December 31, 2009

GNUstep with Eclipse CDT

Although GNUstep has its own IDE and editor, It is possible to use Eclipse for Objective-C projects using CDT, the C/C++ Development Tools.


If you are using Linux, the first thing you need to know about Eclipse is not to install the version packaged with your OS. Ubuntu, for example, is several releases behind on Eclipse. Rather, first make sure you have the latest Java installed (eclipse needs Java), then go to the eclipse.org web site and download it. If you want to use it for both Java and CDT, you can download the one for Java and then add CDT. It's easiest to just install it under your home directory simply by unzipping it there with a command something like...

tar xzvf eclipse-java-galileo-linux-gtk*.tar.gz

Unfortunately, CDT does not directly support GNUstep. You cannot easily import an existing project created by Project Center or create a new GNUstep project with from scratch within Eclipse. Here is one approach suggested in the help-gnustep mailing list by Anne van Rossum (I haven't yet tried this).

- Create sample.m file and GNUmakefile in ObjCProjectExample

- run $GNUstep root/System/Library/Makefiles/GNUstep.sh

- make (that should go fine)

- start eclipse from same console (building/running should go fine)

- add new C project and import directory structure (from ObjCProjectExample)

- at Project - Properties - C/C++ Make Project - [tab] Environment push button Select

- select all environment variables with GNUstep in their names

- apply changes


(Re)Starting Eclipse from whatever location should be fine now. The GNUstep.sh shell script is no longer needed.

[Nicola Pero added...] By the way with the current gnustep-make from trunk, you can also do:


* make sure GNUstep's appropriate dirs are added to your PATH and ld.so.conf [or equivalent to ld.so.conf on your system]


(ie, something like

PATH="$PATH:/usr/GNUstep/System/Tools:/usr/GNUstep/Local/Tools" and adding

/usr/GNUstep/System/Library/Libraries and

/usr/GNUstep/Local/Library/Libraries to your ld.so.conf and rerunning ldconfig regularly)


* set the GNUSTEP_MAKEFILES environment variable (it should be set to
something like /usr/GNUstep/System/Library/Makefiles/)
And then 'make' should work. ;-)

All the other variables are then read automatically by gnustep-make from
the GNUstep config file in /etc/GNUstep/GNUstep.conf.

However, these steps actually seem overly complicated to me. I was able to import an existing GNUstep project into the latest version of Eclipse with the latest CDT with the following steps:

Create a new empty project...



Right click on the newly created project and select Import. Then select General... File System and click Next.


Browse to the project you created in Project Center, click Select All and Finish.

You should now see all your files in Eclipse and should be able to build and run the project.

One oddity is that when you open up a .m file it opens with gedit instead of opening the Eclipse editor. I assume this is because the Eclipse editor doesn't know Objective-C syntax. However, gedit seems to do the color syntax highlighting just fine.

Friday, December 18, 2009

GNUstep Look-and-feel

OpenStep originally was supposed to fit into the look-and-feel of the host system. Consequently, the Solaris and Windows versions of OpenStep looked different, and when OpenStep became the basis for Cocoa on the Apple, the look-and-feel got a Macintosh face-lift. However, Linux has no standard look-and-feel. It all depends on whether you are using KDE or Gnome or whatever.

The GNUstep developers chose to keep the “retro” NeXT look. There is even a desktop on Linux called Window Maker (or wmaker) that is part of GNUstep (or used to be) and implements the old NeXT look-and-feel. However, few people would seriously consider using Window Maker on a regular basis instead of KDE or Gnome (my apologies to Window Maker fans). There is also something called GWorkspace which takes over your desktop and tries to make it look like NeXTstep, but it didn't work right for me when I tried it under KDE4 or Gnome.

By keeping this “retro” look, GNUstep unfortunately makes itself uninviting to most potential users. It also creates a confusion between GNUstep the development environment and GNUstep as a desktop environment.

One feature of GNUstep that can be annoying is the big application icons that appear in the bottom left of the screen when you run a GNUstep application. In Window Maker these would be organized neatly along the right side of the screen, but other window managers just don't know what do do with them.

To get rid of the big icons (I can't think of a reason they will be missed), open a terminal window and type the following command:
defaults write NSGlobalDomain GSSuppressAppIcon YES

You can also change the freestanding menus to be at the top of the screen like in MacOS X using the following command:
defaults write NSGlobalDomain NSMenuInterfaceStyle NSMacintoshInterfaceStyle

However, this will affect other things such as scrollbar style.

To change it back use:
defaults write NSGlobalDomain NSMenuInterfaceStyle NSNextStepInterfaceStyle

There is also a NSWindows95InterfaceStyle, but it won't make your menus appear inside the main menu.

(I think if you set these for your application's name instead of NSGlobalDomain, it will only affect your application.)

In fact, these settings also exist in MacOS X in NSInterfaceStyle.h.

typedef enum {
NSNoInterfaceStyle = 0,
NSNextStepInterfaceStyle = 1,
NSWindows95InterfaceStyle = 2,
NSMacintoshInterfaceStyle = 3
} NSInterfaceStyle;

Apple and Microsoft don't have to support any look-and-feel besides their own. However, if you are producing a cross-platform development environment (like GNUstep), and especially if you are the underdog (as GNUstep is), your programs should behave as expected in whatever environment they are running in. This would be much easier if the GNUstep developers would just abandon the old retro look that simply doesn't appeal to most people anymore.

Tuesday, December 15, 2009

Creating a GNUstep Project

I got the book Developing Business Applications with OpenStep. It's not all I would have wished for. You don't get to your first sample application until Chapter 7, and wading through the first 6 chapters is a bit of a chore. I found Chapter 4 on the Application Kit contains no sample code at all, but it is good for insomnia. Anyway, now that I'm to Chapter 7, Building an Application, I am going to try creating the sample application (PayPerView) which is their only working example and which they add to later in the book when they introduce more advanced topics (this may be the last chapter I read in the book).

PayPerView has a class called ProgramController, which isn't really what it sounds like. The word “program” in this context refers to a pay-per-view tv program. The ProgramController keeps a list of Program objects and interacts with the UI. There is also an OrderController, which controls the process of a user placing an order for a Program. Why there isn't also an Order class I do not know. More classes are added later in the book when the application is expanded to persist to a database and one to use distributed objects. (I am not actually interested in either of these at this time.)

First thing to do is to create the project. In GNUstep, we do this through ProjectCenter. Just like the original Project Builder as described in the book, you choose New... from the Project menu. (Sorry. I am too lazy to paste screen shots in here right now.) I had already created a folder in my home directory called projects_objc. GNUstep creates a GNUstep folder in your home directory for its own configuration files, so better to keep your code separate from that. I'm going to call my application PayPerView and define it as type Application. The default project type in GNUstep is not application but Aggregate. An aggregate project contains multiple sub-projects or “make targets”, meaning it will have multiple executable applications. (You can add new subprojects later even if you select Application at this time.)

On the project window there are noticeable differences between GNUstep's ProjectCenter (PC) and Project Builder. For example, the icons are different. (Still too lazy to do any screen shots, so you'll have to trust me until I feel like adding them.) PC has a screw driver instead of a hammer icon for the Project Builder icon. The remaining icons in GNUstep are different but still reminiscent of the original. That's okay, because there were even significant differences between the NeXT Project Builder and the one that Sun created for Solaris (and, of course, Apple has made significant changes in XCode although it still has the familiar hammer icon). They are the Project Launcher (or Run) icon, the Loaded Files icon, the Project Finder icon, and the Project Inspector (or Attributes) icon.

BTW, at this point if you've never seen XCode it might be best just to ignore it for a while, because it looks so nice while GNUstep looks the same as it did 10 years ago. Just remember that GNUstep is free and not commercially supported.

When you click on Interfaces (as instructed in the book), you will see instead of a .nib file some files related to Gorm, GNUstep's Interface Builder. You get into Gorm by double-clicking on the .gorm file. (Sorry. I am still too lazy to paste screen shots in here right now.)

The format of .nib (NeXT Interface Builder) files were difficult to reproduce in GNUstep, because there is no real .nib file standard. The .nib file is actually just a file containing serialized objects. Duplicating it exactly would have been difficult and possibly required reverse-engineering which probably would create legal problems. However, in newer versions of Gorm, you can at least export to a Nib file by selecting Save As on the Documents menu in Gorm. (I don't think you can import a Nib file created in Apple's XCode and expect to be able to use it in Gorm.)

Anyway, so I will continue later with using Gorm and maybe stop being lazy and add screen shots.

Wednesday, December 9, 2009

Unit Testing GNUstep Programs

As a Java developer who has been trained in test-driven development, I would like to have something similar to Junit for GNUstep/Objective-C. Evidently, around 2005 Apple added a unit testing framework to Xcode 2.1 called OCUnit. OCUnit was not something created by Apple, but they chose to make it the defacto standard by including it in their packages. Unfortunately, this essentially killed off two other competing frameworks, UnitKit and ObjcUnit.

UnitKit is stuck at 1.1 and evidently no longer supported. The GNUStep port is still available from the etoile web site.

http://cvs.gna.org/viewcvs/etoile/Etoile/Frameworks/UnitKit/
http://cvs.gna.org/viewcvs/etoile/Etoile/Services/Developer/UnitTests/

The GNUstep port of ObjcUnit, stuck where is was back in 2002 (v. 1.2) is at:

http://gentoo-portage.com/gnustep-libs/objcunit

Since Apple is distributing OCUnit and the other two are now unsupported, it would at first seem to make sense to try using OCUnit. It is available at...
http://www.sente.ch/software/ocunit/

Unfortunately, although it does support GNUstep, evidently it works only on Mac OS X. Bad news for GNUstep on Linux.

So, we are stuck with using one of the two older, unsupported frameworks or simply doing unit testing with no framework.

Before the creation of Junit it was quite common to test a Java class simply by putting test code in the main method since each class can have a main method. That begs the question, how many main methods can we have in an Objective-C application? Is there one per class or one per application? The answer is one per application, because Objective-C is an extension of C, and there is one and only one main function in any C program (same goes for C++).

I remember in my days as a C++ programmer, I knew people who did unit testing by creating a bunch of Unix shell scripts that called their program in different ways. However, most people didn't even do that. Back then unit tests were usually just a documented list of steps that had to be carried out manually along with expected results. Essentially, you ran the program and if it works without noticeable problems then it passes.

The first unit testing framework that all the others are based on was SUnit by Kent Beck in his 1998 Guide to Better Smalltalk. So, of course, nobody was using these frameworks before then, which makes one wonder if it's really all that important. It has been my experience that most of the time developers don't do true "test first" development in the context of "extreme programming" principles. They write their JUnits after the fact and often only because they are required to by management. Also, unit testing frameworks are pretty good for testing back-end code, but not so much for testing the GUI part of an application.

Don't get me wrong. I like test driven development. However, all things taken into account, I'm not sure I want to spend time writing a bunch of unit tests for a GNUstep program if I can't use OCUnit and there are other ways to get around the testing problem without the need for a testing framework. That's especially true for a program which is only a prototype.

Friday, December 4, 2009

GNUSTEP Projects and Applications

It is entirely possible to create a project manually using a text editor by creating a .m file to contain the Objective-C code and creating a GNUMakefile containing something like the following:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = LogTest
LogTest_OBJC_FILES = source.m
include $(GNUSTEP_MAKEFILES)/tool.make

The above is also from the GNUstep manual.

It is also possible to create an application in Gorm (the GNUstep interface builder) without using ProjectCenter.

However, the normal way to create a project would be with ProjectCenter. ProjectCenter will create several files in the project, including AppController.m. This file doesn't get created when you start an application in Gorm instead.

One of the turorials I found on the internet did not show ProjectCenter creating this AppController.m file, but it was written way back in 2001, so evidently this feature was added since then. This is the tutorial linked from the gnustep.org web site, and it's quite disappointing that a more up-to-date one isn't available. Worse yet, there seems to be no other documentation for ProjectCenter other than a FAQ list.

Another tutorial mentions the AppController, but then since it has you create the application in Gorm, bypassing ProjectCenter, you end up having to create AppController.h and AppController.m in a regular text editor.

There is another program called Project Manager which is supposed to be “an alternative Integrated Development Environment (IDE) for GNUstep”. However, I have noticed that when I'm in ProjectCenter and go to edit code it uses Project Manager. It doesn't seem to matter how I set the editor in preferences. It always uses Project Manager as the editor. I assume this has something to do with the way that GNUstep has been packaged for Ubuntu. Unfortunately, I also have had trouble figuring out how to make the font bigger in Project Manager's editor window, so it is kind of annoying. Of course, you should still be able to edit the files yourself outside the IDE using vim or kate or whatever.

GNUstep Renaissance is an alternative way to develop UI's. It allows you to create GUI's for both GNUstep and Cocoa described by XML documents instead of using Gorm or Interface Builder. I haven't explored this too much yet. It kinda feels like a non-standard way of doing things and it seems like one should learn the standard way first. Also, I don't think there's any way to develop iPhone applications using Renaissance. (You can't develop iPhone applications using GNUstep either. However, you could prototype applications in GNUstep and later port them.)

Installing and Setting Up GNUstep in Ubuntu

Under Ubuntu/Kubuntu, it is quite simple to install GNUstep using the provided packages, but it is another thing to get it to work. The applications will run, but when you try to compile anything it won't find the required make files.


Before you can compile anything, you have to source /usr/share/GNUstep/Makefiles/GNUstep.sh or /usr/share/GNUstep/Makefiles/GNUstep.csh. I think the easiest way to make sure that this always happens is to put a file in /etc/profile.d, call it GNUstep_profile.sh and add the following line to it (requires sudo privilege of course):

. /usr/share/GNUstep/Makefiles/GNUstep.sh


Note that the location of the GNUstep.sh may be different if you install GNUstep from source.




Objective-C

The choice of NEXT (and by extension Apple) to use Objective-C is largely a matter of timing. Java and C# are both derived from C++, but Objective-C has no relation to C++. Stroustrup published his first book on C++ in 1985, the same year Jobs left Apple to start NEXT. At the time, there was, of course, no way of knowing which object-oriented language would become dominant. C++ compilers were not widely available until about 1992.


Fortunately, since Objective-C is also an extension of ANSI C, the syntax is familiar until you get to the object-oriented extensions, but at this point it is, in the words of one blogger, Alan Storm, “deeply, deeply weird”. The syntax for declaring a class and it's “messages” (instead of methods or member functions) is one of the weird things. Here is an example from the GNUstep manual (with comments stripped out).


#include

#include


@interface Test

+ (const char *) classStringValue;

@end


@implementation Test

+ (const char *) classStringValue;

{

return "This is the string value of the Test class";

}

@end


int main(void)

{

printf("%s\n", [Test classStringValue]);

return 0;

}


(This code goes in a file source.m.)


C++ basically duplicated the syntax of a struct in C and added member functions. In fact, if memory serves (it's been years since I've written any C++) you can have member functions in a C++ struct as if it is a class. Then Java got rid of the structs and just has classes. Objective-C took a different route entirely, adding syntax that frankly looks very out of place with the rest of the language. The @ reminds me of annotations in Java.


Not only is the syntax different but the message passing mechanism behaves differently. “The Call vs. Message Sending semantics seem, on the surface, to be the same thing, but my book has promised me there are subtle, yet deeply important differences. The first I’ve encountered is, an object will accept messages that haven’t been defined (it silently ignores them) whereas Java/C#/PHP5 would yell at you for calling an undefined method.” [Alan Storm] Objective-C is also more forgiving if you try to use a null (nil) object.