# $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 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 , you might decide that this will be common in the future, and surround every inclusion of this with #ifdef HAVE_SYS_TYPES_H # include #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 #endif In this way, a system with neither nor 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