NeXTSTEP Development Environment

From Higher Intellect Wiki
Jump to: navigation, search

Q:  How do I specify an icon for my application?  Or for the types of files it uses?  How do I get my application to be launched by the Workspace Manager?


For 2.0:
A:  You'll need to create the appropriate TIFF files and then add them as Project Attributes in InterfaceBuilder.  Here are the steps:

(1)  Make TIFF files for your icons.  You might want two pictures: one for the application itself, and another for files "belonging" to that application.  (For example, WriteNow files ending in ".wn" have their own icon.) Icons may be any depth and the TIFF file can contain multiple images, allowing it to store the look of the icon for different frame buffers.  It's recommended that you use a 48x48 grayscale image, 2 bits per channel, with alpha, and, if your application makes use of color, a 48x48 RGB image at 4 bits per channel, with alpha.  Combine the two images with tiffutil, the command line program.

(2)  Use the Inspector panel in InterfaceBuilder to modify the Project Attributes of your application.  Use the Set button to select the icon you want.  Be sure to add the extension for your documents, without the period.  (If you do include the period, InterfaceBuilder will accept it and compile without complaint, but the extension won't work properlyÐyour documents won't display the specified icon.)   Be sure to save your project, then recompile.

(3)  You do not need to put the executable in your path for Workspace to display the application icon; you only need do this if the application opens documents that you'd like to be able to open by double-clicking.


For 3.0:
A:  You'll need to create the TIFF files and then add them as Attributes in Project Builder.  Here are the steps:

(1)  Make TIFF files for your icons.  You might want two pictures: one for the application itself, and another for files "belonging" to that application.  (For example, WriteNow files ending in ".wn" have their own icon.)  

(2)  Select the Attributes button in the project window. The Application Icon well displays the application icon.  The default application is used if you don't provide one of your own.  To associate a new icon with the application, drag its TIFF file from the Workspace into the well.  The file is copied to the project directory, although it doesn't appear in any of the categories shown in the Files display.  The Document Icons and Extensions well is where you indicate what types of files your application can open.  Drag the TIFF file containing the icon into the well.  Once the icon is in the well, change its label to match the file  extension. Be sure to save your project, then recompile.

(3)  You do not need to put the executable in your path for Workspace to display the application icon; you only need to do this if the application opens documents which you'd like to be able to open by double-clicking.


QA97

Valid for 2.0, 3.0, 3.1
Q:  I thought that an #if 0 block will ignore everything inside it.  But it doesn't.

A:  The ANSI standard says that #if statements only ignore syntactically correct code.  So if there are syntax errors, you get an error.  Two particularly nasty ones are unterminated comments, and unterminated string constants.  See examples below.

/tmp/foo.c contains:

	#ifdef NEVER 
	/* this is the start of 
	a comment that never ends
	#endif

/lib/cpp /tmp/foo.c generates:

	/tmp/foo.c:1: unterminated '#if' conditional

Or, /tmp/foo.c contains:

	#ifdef NEVER
	some words with a single quote ' OK
	#endif

it generates:

	/tmp/foo.c:2: unterminated string constant
	/tmp/foo.c:1: unterminated #if conditional

Note: In 3.0 or 3.1, the error generated reads:

	/tmp/foo.c:2: unterminated character constant

QA454

Valid for 1.0, 2.0, 3.0
NEXTSTEP

Title: Where is libcs Located? 

Entry Number: 1421
Last Updated: 24 August 1994
Document Revision: 894A

Keywords: libcs

Question

I just installed NEXTSTEP Release 3 and discovered that the library libcs.a is missing.  What happened to it and where can I get it?

Answer

The libcs library has been removed from Release 3 (and beyond).  The libcs library was written at Carnegie Mellon University. It can be obtained, in source form, from the Stepwise NEXTSTEP/OpenStep FTP Server.  To obtain libcs you need access to the Internet. To retrieve the source via ftp, issue the following commands (in bold):

localhost> ftp ftp.stepwise.com
Name (ftp.stepwise.com:username): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:
ftp> cd pub/Source/Libraries 
ftp> bin
ftp> get libcs.tar.gz
ftp> bye

If you have access to the World Wide Web, you can get the library by accessing the following URL:

ftp://ftp.stepwise.com/pub/Source/Libraries/libcs.tar.gz
Q:  I have libraries compiled for NeXT 3.0 machines that I need to use on NEXTSTEP for Intel Processors.  What should I do to make them work?

Q:  I wrote an application under 3.1 on an Intel NEXTSTEP platform that uses a library I wrote under 3.0, but it won't link properlyÐwhy?

Q:  How do I make my 3.0 libraries accessible in a multi-architecture form to 3.1 applications?

A:  Libraries that were compiled under NEXTSTEP 3.0 and earlier should work fine under 3.1Ðfor NeXT hardware.  Some extra work is required to make them work properly under NEXTSTEP 3.1 for Intel Processors.  Because the m68k architecture and the i386 architectures are radically different, it is necessary for NEXTSTEP to have access to a binary for both architectures in order to provide an executable that runs on both machines.  Libraries, being binary files containing machine instructions, are no different from any application in this respect.  Building multi-architecture applications is easy, since the Project Builder application takes care of the details of building Multi-Architecture Binary files (MAB files) when requested.  But Project Builder doesn't manage libraries, so an application that you have compiled may fail to link properly because of the lack of a library matching the architecture type of the machine you are compiling for.

3.1 provides a new utility, libtool, for generating multi-architecture (or "fat") libraries.  libtool is intended to replace both the ar and ranlib utilities.  Traditionally, the construction of a library is managed by a Makefile, which usually does roughly the following:

1)	Compiles the .c and .m (source) files into .o (object) files, using the compiler (cc).
2)	Archives the resulting .o files into a .a (library) file, using the archiver (ar).
3)	Generates a table of contents file in the archive, using the ranlib utility.

A simple sequence to generate a linkable library starting from just two C files might be:

	/bin/cc -c -o first.o first.c
	/bin/cc -c -o second.o second.c
	/bin/ar ruv libsilly.a first.o second.o
	/bin/ranlib libsilly.a

Under 3.1, however, steps 2 and 3 above are combined into one libtool call, so that the equivalent sequence would be:

	/bin/cc -c -o first.o first.c
	/bin/cc -c -o second.o second.c
	/bin/libtool -o libsilly.a first.o second.o

Notice that the call to ar, with the r, u, and v switches on, has been replaced with a call to libtool, and that calling ranlib is no longer necessary.  The r, u, and v switches allowed ar to update only the objects that were newer than the ones in the archive; the libtool call doesn't have this capability, but is much faster than ar, and in addition, it is capable of archiving fat objects, which ar cannot do.

So where do multiple-architecture objects come in?  So-called "fat" objects are generated when the compiler is told to generate objects of more than one architecture type, using the -arch flag.  If you look at the compile text field in Project Builder, you should notice that it uses this flag whenever it is asked to generate something for both the m68k and i386 architectures.  The change needed to the above sequence is:

	/bin/cc -arch m68k -arch i386 -c -o first.o first.c
	/bin/cc -arch m68k -arch i386 -c -o second.o second.c
	/bin/libtool -o libsilly.a first.o second.o

And that's all there is to it.  The gains to library-building using libtool are the ability to make fat libraries, and the elimination of the need to use ranlib.  The loss is the ability to update only those files in the archive that have timestamps older than the input filesÐin general, the amount of time lost in moving from ar and ranlib to libtool should be minimal, if any.

For the Makefile minded, here's a simple example of what needs to be changed.  The first file is the original, which compiles into a single-architecture library, and the second file will generate the multi-architecture library:

	-------------------------------
CC		= /bin/cc
RANLIB	= /bin/ranlib
AR		= /bin/ar
ARFLAGS	= ruv

CFLAGS	= -g -O2 -arch m68k -arch i386

SRCS		= first.c second.c

OBJS = $(SRCS:.c=.o)

.c.o: ; $(CC) $(CFLAGS) -c -o $@ $<

all: libsilly.a

libsilly.a: $(OBJS)
	$(AR) $(ARFLAGS) $@ $(OBJS)
	$(RANLIB) $@

clean: ; /bin/rm -f *.o *.a *~
-----------------------------------
CC		= /bin/cc
LIBTOOL	= /bin/libtool

CFLAGS	= -g -O2 -arch m68k -arch i386

SRCS		= first.c second.c

OBJS = $(SRCS:.c=.o)

.c.o: ; $(CC) $(CFLAGS) -c -o $@ $<

all: libsilly.a

libsilly.a: $(OBJS)
	$(LIBTOOL) -o $@ $(OBJS)

clean: ; /bin/rm -f *.o *.a *~

--------------------------

See Also:

Man Pages:  lipo(1), libtool(1), ar(1), ranlib(1).
Release Notes:  Compiler.rtf, FatFiles.rtf, ProjectBuilder.rtf

QA883

Valid for 3.1
Q:  I've made connections in InterfaceBuilder like I have a zillion times before.  So, why are all of my outlets nil when I run my program?

A:  In earlier releases, you had to provide a method to set each outlet that you declared in a new class.  For example, if your subclass had an outlet named myOutlet, the source code for your subclass had to declare and implement this method:

	- setMyOutlet:anObject
	{
		myOutlet = anObject;
	 	return self;
	}
	
In InterfaceBuilder, the Unparse command in the Classes window's pop-up list would create these "set" methods automatically.  

These outlet initialization methods are no longer required.  However, for backward compatibility, if an object responds to such a message, the runtime system uses them to initialize outlets.  Basically, the runtime system does this:
	
	if ([yourObject respondsTo:@selector(setMyOutlet:)])
		setMyOutlet:anObject

All is hunky dory, if you remember the days when these methods were required.  Now that InterfaceBuilder does not generate them automatically, it is not obvious that these method names have special meaning.  So, if you have a method name setMyOutlet you must set the outlet within that method.  If you don't initialize the outlet, then myOutlet is nil at runtime.

Overall it is best to avoid setMyOutlet style method names altogether, unless you are consciously taking advantage of this "feature," and are doing additional initialization within the "set" method.  Care must be taken, as the order in which outlets and other objects are  initialized is neither guaranteed nor predictable.

QA772

Valid for 1.0, 2.0, 3.0
Q:  How do I create hierarchical views in InterfaceBuilder?

A:  The only ways that InterfaceBuilder provides are:

1)	You can use the Group command while a number of views are selected.  This creates a Box object that encloses these views, becoming their superview.  If you don't want a title or a border use the Inspect command, set the No Title and No Border options, and then set the horizontal and vertical offsets to 0. 

2)	Starting with Release 2, there is a Group in ScrollView command. By choosing this command, you can put any selected View in your application's window into a ScrollView.  See the 2.0 or 3.0  InterfaceBuilder release notes.

Note: For NeXTSTEP Release 3, you should use the Inspector command from the Tools menu to open the Inspector panel, then follow the steps described in (1) to set the grouping attributes.

QA153

Valid for 1.0, 2.0, 3.0, 3.1
Q:  How do I create a nib module that is owned by something other than a subclass of application or a subclass of object?

A: When you create a new module, InterfaceBuilder prompts you to choose what is going to own it:  a subclass of object or a subclass of application.  If you had planned for the owner to be one of those two, that works well.  But what if you want the nib module to be owned by a subclass of a subclass of Object or by a subclass of Control or any other class in your class hierarchy?  When you first create the new nib module, go ahead and indicate to InterfaceBuilder that you want it to be owned by some subclass of Object.  We will change it later.  Add the class you want as the owner to your class hierarchy.  Select the File's Owner icon in the nib window of InterfaceBuilder (the small window with the icons in the lower left corner of screen).  Choose Attributes from the Inspector panel pop-up list.  There is a scrolling list of custom classesÐselect your custom class from the list and click "OK."  You've done it!

Note that in NEXTSTEP Release 3 your custom class is automatically selected once you click a selection from the list. The "OK" button has been removed. 

See also IB_file_owner (ib.510).

QA511

Valid for 1.0,  2.0, 3.0


Share your opinion