Portable Object Compiler (c) 1997,98,99.  All Rights Reserved.



                           N O T E S   P O R T I N G
			   -------------------------

This file contains some notes on porting the Object Compiler (objc)
to new platforms, in absence of a bootstrap Objective-C compiler.

You need two machines.  They are best networked since you have transfer
sources between them (certainly useful when you have to debug things).

TARGET is the machine you want to port to,
HOST is a machine for which the Portable Object Compiler is already available.

The port consists of generating, on the HOST, C sources for the Objective-C
compiler source, but with system header files of TARGET 'embedded' in the
generated C source.

1.  Move the /usr/include header files of TARGET to the host.

	TARGET
	
		cd /usr
		tar cvf include.tar include
		rcp include.tar HOST:$HOME
	
	HOST
	
		cd $HOME
		tar xvf include.tar
		
2.	Figure out how the C preprocessor is ran on TARGET

	TARGET
	
		cd /tmp
		touch testfile.c
		cc -c -v testfile.c
		
	This gives for example on FreeBSD :
	
/usr/libexec/cpp -lang-c -v -undef -D__GNUC__=2 -D__GNUC_MINOR__=6 -Dunix -Di386 -D__FreeBSD__=2 -D__unix__ -D__i386__ -D__FreeBSD__=2 -D__unix -D__i386 -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386) testfile.c /var/tmp/cc004269.i

3.  Set the C preprocessor flags on HOST

	HOST
	
	(for FreeBSD, substitute approriate flags as obtained in step 2 !)
		
	setenv TARGETFLAGS "-D__GNUC__=2 -D__GNUC_MINOR__=6 -Dunix -Di386 -D__FreeBSD__=2 -D__unix__ -D__i386__ -D__FreeBSD__=2 -D__unix -D__i386"
		
4.   Set the Objective-C cross compiling flags on HOST

	HOST
		
	    configure -e AR=echo -e RANLIB=echo
	
	this configures the sources so that AR and RANLIB do nothing (because
	we will have no .o files)
	
	    setenv OBJCOPT "-undef $TARGETFLAGS -C -nostdinc -I$HOME/include"
	    setenv OBJCOPT "$OBJCOPT -postlink"   (*)
	    setenv OBJCOPT "$OBJCOPT -noTags"
	
	-C instructs to generate C source only.
	-nostdinc -I$HOME/include instructs to embed TARGET system headers.
	-undef $TARGETFLAGS forces cpp to use TARGET cpp flags.
	-postlink : see 4b to decide whether you want to add this
	-noTags : can be useful, for step 6

	(*) if you use -postlink, don't forget to use util/_objc1.c etc.

4a.	Check whether HOST is a NEXT machine, and TARGET is a non-NEXT 

	If yes,
	
		setenv OBJCOPT "$OBJCOPT -init _objcInit"
			
	This is because our NEXT compilers are configured with
	oc_objcInit as objcrt runtime initialization function
	by default, while other compilers use _objcInit, and we have
	to generate source code for the other platform.

4b.	Decide whether to use POSTLINK for bootstrapping.

	If you port to a compiler that does not provide common storage
	of uninitialized global variables, then make a POSTLINK
	compiler.
	
	If yes,
	
		setenv OBJCOPT "$OBJCOPT -postlink"
			
	How to find out whether your compiler supports common storage of
	uninitialized globals?
			
		TARGET
			
		echo >foo.c 'int a;void main() { printf("%i\n",a); }'
		echo >bar.c 'int a = 10;'
		cc foo.c bar.c;a.out
			
	If this prints "10", then your compiler supports this 'K&R C feature'.
	Many ANSI compilers do, eg. 'gcc' does, but 'gcc -fno-common' does not.
	
	NOTE: making a POSTLINK compiler for bootstrapping is a good idea, even
	if the compiler supports common storage of uninitialized globals, and 
	it is in fact not more work (it is the safest option).

5.	Precompile (obtain .i files) for "objcrt", "objpak", "oclib" and 
        "objc1".

	HOST
		
		cd src/objcrt;make
		cd src/objpak;make
		cd src/objc/oclib;make
		cd src/objc;make objc1
		
	You don't need to (and should not) precompile any C++ (*plus.m) files
	or objc.m, only the files : name.m, objc1.m, parse.ym and scan.lm.

6.  Compile generated .i files on TARGET

	HOST
	
		cd src
		mkdir bootsrc
		mv */*.i */*/*.i bootsrc
		tar cvf bootsrc.tar bootsrc
		rcp bootsrc.tar TARGET:$HOME
		
	TARGET
	
		tar xvf bootsrc.tar
		cd bootsrc;cc -c *.i;
		
6a.	This is an optional step.  Only needed if you decided, in 4b, to make
	a POSTLINK compiler (and used -postlink for generation of C sources).
	
	Add & Compile a _postlnk.c file.

	The _postlnk.c file is a file that contains a list of all modules that
	are linked into "objc1" (for runtime initialization).
	
	It is the output of "nm objc1 | awk -f postlink.awk" (assuming that
	objc1 is not stripped).  In case you don't have a non-stripped objc1
	executable at hand, the file is listed at the end of this file.
	Copy it into a file called _postlnk.c and :

	TARGET

		cc -c _postlnk.c
	
7.	Link executable

	Now link the executable (.o files for all .i files [ +
	_postlink.o if you made a POSTLINK compiler]) 
	
	TARGET

		cc -o objc1 *.o

8.	Test executable

	TARGET

		./objc1 -version
		
	If this prints the version, then you are executing Objective-C on 
	TARGET.
	(it's not just a printf() statement).
	
9.  Move the objc1 binary that we've made, into a bootstrap "bin" directory.
	Make a backup of it (objc1-1).
	
10. Modify flags in the configuration script 'configure' for the new platform.

11. Run the configure script on TARGET

12. Copy src/objc/objc (the driver for TARGET) into a bootstrap "bin" directory
    (the location where objc1 for TARGET is)

13. setenv OBJCDIR ...;set path = ($OBJCDIR/bin $path)

	If you do now "objc --version" it should show a version message for TARGET.

    Run configure script again for compiling with the bootstrap compiler.

14. Try to do a regular compile of the Portable Object Compiler sources.
    Recompile the compiler a couple of times with itself.


---------------------------- objc1 _postlnk.c -------------------------------

This file appended here merely for convenience while porting :

---------------------------- objc1 _postlnk.c -------------------------------

[this data is now available in util/_objc1.c and util/_objc.c]

