# $Id: PORTING,v 1.1 94/08/02 00:00:00 lee Exp Locker: lee $

Notes for porting lq-text.

These notes are not as well organised as they should be (sorry).



This is the free version.  It is not public domain, but you can use it
freely for non-commercial purposes.

If you want to sell it, or something derived from it, you should get in
touch with the author (me!), who will almost always give permission.

You can contact me as follows:
  lee@sq.com,
  Liam Quin, SoftQuad Inc. 56 Aberfoyle Crescent, Ont, CANADA M8X 2W4
  (+1) 416 239-4801

The ftp site for lq-text is ftp.cs.toronto.edu in the /pub directory.

==============================

PORTING NOTES

See ../INSTALL for how to do an installation on a system to which lq-text
has been ported already; this involves running "configure".

This document explains how to add a new machine to the configure database.
It isn't hard, don't panic...


Likely problems:
* configure doesn't work at all, and says `syntax error'
  It needs a shell with shell functions.
  Type this and see if you get a syntax error:
##############
feet()
{
    echo bare
}
##############
  If you don't get an error message, check that typing
feet
  produces the message
bare
  If you got errors, or you didn't get the "bare" message, you are faced
  with some choices:
  (1) find another shell.
      On Ultrix systems, /bin/sh5 will do.
      The GNU/FSF Born Again Shell (bash) is another possibility, as is ksh.

      for example, instead of
configure
      type
bash configure
      and see what happens.
  
  (2) do the configure by hand
      look in config.dir to see if you are using a machine listed there;
      for each machine, there is a directory for each operating system which
      that machine can run.  If your system is there, you're in luck.
      For example, if you are using an Intel 586 system running Solaris 2.4,
      look for
	config.dir/x86/solaris-2.4
      and if it's there, you've got a config directory.
      If not, you might be able to find a similar one to start from.

      In this case, there may be some files ready for you in that directory;
	Makefile.tpl
	Makefile
	cflags.def
	port.h
	port2.h
	build.sh
      
      [1] Copy Makefile to src/Makefile
	  If it's not there, and you have only Makefile.tpl,
	  edit src/Makefile by hand.

	  You can look at cflags.def to see what C compilers other
	  people have used to compile lq-text, and copy the appropriate
	  part of cflags.def into Makefile.

      [2] copy port.h to src/h/port.h

	  If there isn't a port.h, you can look at build.sh to see the
	  settings for the various variables, and edit h/port.h accordingly.

      [4] copy port2.h to src/port2.h

	  This file is optional, so don't panic if you don't have one --
	  simply make it an empty file.
      
      Now proceed with the installation instructions in ../install as if
      configure had worked.  Please accept my apologies, and feel free to
      let me know what system this is and what problems you had, so that
      I can try and make configure work better on it next time.

  (3) Treat it as a new port -- see `Extending Configure' below.


* This release does not support the sharing of an lq-text database
  across write-enabled NFS mounts.  In other words, if you want to have
  multiple machines sharing the same database, you can only ever
  write to the files on one of the machines -- designate that machine
  as a master.   Releases of lq-text prior to 1.8 (1992 or so) used to
  support this, but there were large performance penalties.

* In this release, the binary index files are architecture specific:
  you can't take an index that you created on SPARC system and use
  it on an Intel 80x96 system, for example.  If you need to do this,
  please contact me (lee@sq.com) and I will try and help you.  It's
  probably a day or two's work to change, at the expense of a
  performance penalty on one or the other system, depending on which
  you decide to make `native'.  You will have to use the BSD db package,
  not sdbm or ndbm.

* db didn't compile
  You can use sdbm instead.  Look at Makefile for the things to change.
  If you use gdbm, please be careful to read COPYRIGHT and compare it to
  the GNU copyright.  If it's OK, you can proceed...
  If you end up fixing db, you can mail me (lee@sq.com) or Keith Bostic
  (his address is in the db package) or, better, both, to let us know.
  Please contact me (lee) with problems in the first instance, though,
  in case they are to do with the lq-text environment.

* On mixed model architectures, or non-32-bit systems, make sure that:
  . you can have arrays larger then 64 KBytes;
  . a pointer (char *) is the same size as an unsigned long, so that
	unsigned long ul; char *cp;
	ul = (unsigned long) cp;
    and
	*cp = (char *) ul;
    both work correctly.  If you don't know how to test this, please
    try and get local help before asking me.

* see the TODO file for functionality not yet available

* Problems with Curses are common.
  In the lqtext program, you can use control-D as a synonym for F1.

  The X Windows (XView and Motif) interfaces are not included with this
  release; mail lee@sq.com if you are interested in these, or in
  possible Java or Tcl/Tk interfaces.

  The http (WWW) interface is new.

  The "lq" interface is the most heavily tested in this release.
  lq-text is generally best used as a back-end, so I have not
  concentrated on user interfaces.  Sorry.


By all means mail me with questions, providing that you have at least tried
to get somewhere youself.

Lee

lee@sq.com (Liam R. E. Quin)


Extending Configure
===================

:overview

The lq-text "configure" is a (fairly complex) shell script that:
* asks you what kind of machine you are using
* asks you which operating saystem you are running
* uses these to work out a default configuration for compiling and installing
  lq-text.

It uses a directory structure like this:

lq-text/configure -- the shell script
lq-text/config.dir -- the library of information about ports

The result of running configure is normally that you have the following
files installed:
    src/Makefile -- top-level Makefile for lq-text
    src/h/port.h -- platform-specific C definitions
    src/h/port2.h - a place-holder for local definitions

Every lq-text source file includes "globals.h", and this in turn includes
port.h at the top, and port2.h at the end.  It is *much* better to make
changes to port2.h than to globals.h, as then your changes can be used by
other people on your platform without affecting other platforms --
globals.h is used on all systems.

If you don't want to use configure, you don't have to.  You can edit the
three files yourself and go ahead with "make".  But if you are doing a new
port, and send me (lee@sq.com) your new config.dir subdirectory, as
explained below, I will almost certainly include it in the next release,
along with any changes to the actual C files, and you will have much less
work to do next time round, as will other people using the same platform.

I have used my own "configure" script because I couldn't find one that
did what I needed, didn't do lots of other things, and didn't use a
licence incompatible with the lq-text COPYRIGHT.  I understand that the
GNU AutoConf package may in fact now be suitable, and I may move to
it in a future release.


:detailed-description

config.dir contains these files:
  config.dir/local.sh -- previous settings, or an empty file
    as lq-text is shipped, this is set up for a Sun SPARC running SunOS 4.x
  
  config.dir/default.sh
    this is used if there isn't a "build.sh"; if your local.sh is ill,
    you can remove that, and configure will start again with default.sh.
  
In addition, there is a directory for each kind of CPU or hardware,
such as sparc, x86, mips, etc., and a directory called default.

There is also a directory called tests, described later.


Each of the per-CPU directories contains a directory for each supported
operating system, and also a directory called "default".

The default directory is used as a starting point for a new port.


When you tell configure that you have some kind of computer it doesn't
know about, it asks you again (in case you made a typo) and gives you
the list of ones it knows about -- i.e. the directories under config.dir.
If you insist, a new directory will be created, and it will contain
a directory "default", whose files are copied from the default directory,
config.dir/default/default/*

If the hardware directory already existed, but the operating system didn't,
and you insist (again), configure will create a new directory underneath
config.dir/${HARDWARE}, so if (for example) you choose x86 as your hardware
and solaris-2.4 as the operating system, and that didn't exist, configure
would create the directory x86/solaris-2.4, and copy x86/default/* into
that new directory.

I'm telling you this so that when you do your port, you can change the
default files too if you need to.

The files are:
* Makefile.tpl -- a template makefile that gets edited later
* cflags.def   -- information about the C compilers on this system
* build.sh     -- contains default variable values for this platform.
These files are describes in more detail below.


Once you have chosen hardware and operating system, configure checks each
of the variables in the tests/scripts file that is unset or is set to
unknown in the build.sh in the porting directory.

For each such variable, there is (or should be!) an entry in
	tests/scripts
that includes a shell-script to run to determine the value.  There are 
some comments in tests/scripts that may help you add to this if you need
to; more about that later!


When it's finished with tests, configure writes out some files in the
porting directory:
[1] cflags.def
    This file contains a group of lines for each different C compiler.
    Each group starts with a line of the form
	@CC=${CC}
    where the @ is at the start of the line and ${CC} is actually the name
    of a C compiler, for example
	@CC=/usr/ucb/cc
    The group ends just before the next line starting with an @-sign; this
    is why the file ends with "@End".
    All the lines in the group will be copied into the top-level Makefile
    unchanged, although if you use configure to edit the C flags, comments
    and variables unknown to Configure will be deleted.
    The best way to pass comments through to Make at the moment is to use
    @@ the comment

[2] Makefile
    This is a copy of Makefile.tpl in the same directory, but with the
    following changes between the lines that say
## Local Changes, generated by the configure script:
		<-------------- here
## End of Configure output. 
    No changes are made to Makefile.tpl anywhere else.

    The changes are:
    * the cflags.def file is included, all commented out except for the
      section for the C compiler you chose in Configure.
      When the file is included, all leading @-signs are turned into #-signs.
      This may seem odd, but it lets you put comments inside the cflags.def
      file on lines starting with a #, and they'll get copied through to
      the Makefile -- the @ is considered "out of band", and would be
      illegal at the start of a line in most versions of make.

    * all of the variables in the tests/scripts file that are marked as
      being of type "make" are included with their values.

[3] port.h
    This will later be installed as src/h/port.h.
    Every C file (*.c if you will) in lq-text includes src/h/globals.h,
    which in turn includes src/h/port.h.

    This file is created by configure, and contains values for all of
    the variables of type "C" in tests/scripts -- for example
	#define HAVE_UNISTD_H 1
    or
	#undef HAVE_UNISTD_H
    
    You should not edit port.h by hand.  If you need to make changes,
    make them in port2.h instead...

[4] port2.h
    If this file does not exist, configure creates it as an empty file.
    Of course, it may have been copied from the default directory for this
    CPU hardware when the port to this operating system was started.
    After that point, configure won't touch port2.h except to install it
    in src/h/port2.h.  The header file src/h/globals.h includes port2.h as
    the very last thing it does, to give you a changce to override any
    of the definitions in port.h if configure gets them wrong.
    Sometimes this is easier than fixing the script that generates the
    incorrect value, or there may be a variable you definitely only need
    for this machine.

    Good candidates for port.h are header files like "bsdcompat.h",
    and odd-ball definitions like NEED_POSIX_SOURCE_EVEN_ON_WEDNESDAY which
    some vendors use to make porting harder.

    If the line
    :!cp -i % /some/where/port2.h
    appears in this file; in the vi editor, you can move onto it,
    edit it to make the directory correct if necessary, then
    save the file (:w) and then do
	"ayy@a
    to copy port2.h back to the config directory.
    That way, next time you do a configure, your changes won't get lost.

[5] build.sh
    This contains all the variables with their values, and also gets copied
    to config.dir/local.sh, so as to set them up as defaults for next time.
    Note that choosing a different C compiler will reset most of the
    variables to "unknown", and the scripts will be run to determine
    the proper values.

These generated files are copied as follows:

    Makefile	src/Makefile
    port.h	src/h
    port2.h	src/h

    For each of them, configure asks you if you want to overwrite the
    current copy or not, and also lets you run diff to see what changed.

Once you have run configure, you should cd into src and do the following:

[a] cd src

[b] Edit h/globals.h
    This file cotains per-site configuration information, rather than
    per-platform information.  You shouldn't have to change this file
    for a new port, but you might want to make changes for your local site.

[c] Edit Makefile
    Any changes you make here will get lost if you run configure again,
    so it's better to make changes to config.dir/$HARDWARE/$OS/makefile.tpl
    if you can.  If this is a new port, remember to make your changes
    to config.dir/$HARDWARE/default/Makefile.tpl too, to help the next
    person doing a port to another operating system on the same
    hardware.  This might be you after you have upgraded the O/S!

    The most likely change is to choose a dbm clone such as db or sdbm.

[e] build the software
    make

If this goes OK, you can try
    make -n install
to see what it will do, and then
    make install
to do it.  Currently, man pages are not installed.


:Extending Configure

The most common thing to do is to add a new test for a feature, either
in make or in C:

(a) invent a name.
    Conventions:

    The presence or ansence of a feature is tested against with
    #define HAVE_FEATURE
    or
    #define HAVE_HEADER_H
    if the feature is available, and
    #undef HAVE_FEATURE
    otherwise; this is used as
    #ifdef HAVE_FEATURE
	good code
    #else
	fallback code
    #endif

    Don't invent names like HAVE_OS360, HAVE_MSDOS or HAVE_SYSV.
    Instead, have a name for a specific feature.
    For example
	HAVE_BCOPY -- the bcopy() routine is available
	HAVE_STRINGS_H -- the <strings.h> include file is available
    In this way, hybrid systems that are based on System V (say) and
    have a lot of BSD features can be accommodated.
    It's better to have 100 specific tests than to overload a few
    tests such as #ifdef BSD, particularly when 4.4BSD is really
    very different from the 4.1 BSD of a dozen years ago...

    Your name must be suitable for a Make variable, a shell (sh) variable
    *and* a C #define.  It must not conflict with Make, sh or C builtins
    such as __FILE__ or PATH.  The rule is that it must start with a
    capital letter, and contain only capital letters and underscores.
    If you really must, you can probably put a digit in it, but not at
    the beginning.  HAVE_WAIT4 will work, but 4LOVE isn't.

(b) tell configure about your new name

    See the comments in config.dir/tests/scripts, where you do this.

(c) write a test for your feature

    Again, see the comments in config.dir/tests/scripts.
    The test can assume that all variables earlier in the scripts file
    have been set appropriately, although the fewer it depends on the
    better.

    Your script should print the appropriate value of the variable to
    stdout.  For a cpp define, this is generally one of
	#define NAME yes
    or
	#undef NAME
    or empty.
    For a Make variable (e.g. RANLIB), it's usually something like
	ranlib
    or a path name, or empty.

    Note: configure assumes that the value "unknown" is out of band,
    i.e. that it is not a legal value for any variable.

    Since the output of your script is redirected, errors must be sent
    to the terminal (stderr) directly, for example:
	echo "$0: can't determine ankle circumference, assuming 21 cm" 1>&2
    Note the 1>&2 at the end of the line; this is shell magic for printing
    to file descriptor 2 (standard error, stderr).

(d) edit the source

    If it's a C define, you'll need to edit the source to make it
    look at the variable, for example if you port to a system without
    <sys/types.h>, you might decide that this will be common in the future,
    and surround every inclusion of this with
	#ifdef HAVE_SYS_TYPES_H
	# include <sys/types.h>
	#endif
    Probably there will be some other header file you use on your system.
    Don't assume you can simply use #else, but add something like
	#ifdef HAVE_OS_TYPES_H
	# include <os/types.h>
	#endif
    In this way, a system with neither <sys/types.h> nor <os/types.h> can
    be accommodated.

(e) run configure again.  You might want to do
	sh -x configure
    to see when your script is run, or put debugging code in the script,
    as in
	echo "$0: arguments $*" 1>&2
    at the start, for example.


A future version of configure might not use shell functions.  Let me know
if this would help you.

Lee