This file describes how to install the Scheme interpreter and the extensions to the interpreter and how to port it to a processor or operating system not supported by this release. You want to read the release notes (RELEASE) and the files ORIGIN and README in this directory before proceeding. SUPPORTED ENVIRONMENTS The processor/operating system combinations on which this software has been tested are called "supported environments". While installing the software in a supported environment is simple (mainly a matter of typing "make"), additional efforts may be required to install it on a different processor or operating system. This may be as simple as adding a line to a Makefile, or it may require you to write some lines of assembly code. Supported environments of this release are Sun-3 with SunOS 4.0 Integrated Solutions 680x0 with 4.2BSD or 4.3BSD Vax with 4.3BSD (or Ultrix) Intel 80386 with UNIX System V Release 3 It is expected that the software can be installed without modifications in environments closely resembling those listed above, e.g. XENIX or older versions of SunOS. If you want to install the software in an environment not supported by this release, you should first ask the author (me) whether it has already been ported by someone else since this release has been published. This may save you the effort of applying the necessary modifications yourself, and it avoids duplication of work. Likewise, if you have ported the software to a new environment, you can help saving other people's work if you send me the modifications (my electronic mail address is in the file ORIGIN). This helps me increasing the number of supported environments in the next release, and it enables me to act as a "clearing house" for official modifications to the software. If you want to port the software to a new environment, read the chapter "PORTING THE SOFTWARE" below, then come back to this point. INSTALLING THE SOFTWARE Before compiling the sources, you have to modify a few lines in the Makefile in this directory. This Makefile invokes "make" on the individual Makefiles in the sub-directories to make the interpreter and the extensions. Never modify one of the Makefiles in the sub-directories or directly invoke "make" in a sub-directory, since the CFLAGS and other definitions are propagated from the top level Makefile to the "inferior" Makefiles. 1) First insert the name of the directory where the Scheme files reside into the line beginning with SCHEME_DIR=. This is usually the top level directory of the distribution (the directory where you are now) with "/scm" appended. However, you might want to move the Scheme files to a different directory (e.g. /usr/local/lib/scm). Be careful to not delete any backslashes or quotes when editing this line. 2) Insert a symbol indicating the type of processor into the line beginning with MACHTYPE=. In the current release, permitted values of MACHTYPE are 68k for the 680x0, vax for the Vax, and 386 for the Intel 80386. MACHTYPE is used to determine which of the assembly files in the src directory will be used; it is actually a file suffix. 3) Decide which CFLAGS and LDFLAGS you want to use. Remove the '#' in front of the correct definitions for CFLAGS and LDFLAGS and comment the lines out that have previously been in effect. Note that under SunOS -Bstatic has to be used to make sure that the interpreter is statically linked. When you want to use the GNU C-compiler, on some systems it may be necessary to add -ftraditional in order to correctly compile the include file . 4) Type "make". This makes the interpreter (in src) and all extensions (lib, lib/xlib, lib/xt, lib/xaw and lib/xhp). If you don't want to compile everything (e.g. when you don't have the X window system) invoke "make" with a list of TARGETS, e.g. "make TARGETS=src" to only make the interpreter or "make 'TARGETS=lib/xaw lib/xhp'" to make the interfaces to the Athena and HP widgets. Never invoke "make" directly in one of the sub-directories since in this case the correct definitions for CFLAGS etc. will not be in effect. 5) When the compilation has finished, the Scheme interpreter is in the file src/scheme. Invoke it and load some programs from the tst and scm directories to make sure that it works. If you have the X window system try to load the demonstration programs in lib/xlib/examples and lib/xt/examples. If "dumping" is supported on your system, try something like "(dump 'foo)", leave the interpreter, and then try to execute "foo". If everything works fine you should make the interpreter available to all users of your system by moving it to /usr/local (or where-ever you install new executables). Do not strip the executable; the symbol table is required for dynamic loading and "dumping". 6) On systems that do not support dynamic loading (typically System V), the extensions that you are going to use (e.g. the interface to the Xlib) must be linked together with the interpreter statically, since they cannot be loaded during runtime. Since there is no rule in src/Makefile to accomplish this, you should either add the names of the object files (e.g. ../lib/xlib.o) to the rule for "scheme" or link the object files by hand: cd src cc -o scheme *.o ../lib/xlib.o [other extensions] -lm -x Then rename the interpreter to something different from "scheme" (e.g. "xscheme"). This causes the interpreter to initialize the extensions on startup (by reading its own symbol table and invoking all initialization functions and C++ static constructors). In general, this kind of initialization is performed when 1) INIT_OBJECTS is defined in src/config.h and 2) the name of the interpreter is not equal to "scheme". PORTING THE SOFTWARE 0) Requirements on the target environment: The C language implementation must support alloca(). The semi-portable alloca() by Doug Gwyn cannot be used; alloca() must actually extend the stack. The C compiler must be able to accept long input lines (at least 2500 characters). The software probably cannot be easily ported to systems with less than 32 bits for the representation of pointers and integers. It has not yet been tested on systems with larger representations; in this case it may be necessary to modify the representation of Scheme objects (src/object.h). The representation of Scheme objects (src/object.h) currently assumes that only the VALBITS low order bits of a pointer are used. If some of the high order bits of a pointer are non-zero on your machine, the macros POINTER, SETPOINTER, and SET in the file src/object.h must be modified accordingly. The operating system must provide for blocking and re-enabling signals for critical sections without the danger of signals getting lost due to this blocking. 1) If you are porting the software to a type of processor not mentioned in the list of supported environments, you must first provide a working version of the assembly file src/stack.s. The file doc/stack.txt contains instructions how to write a new stack.s; the directory "stk" holds two simple test programs that should be used to make sure that the new stack.s is working correctly. Then move the new stack.s to src/stack.s.MACH, where MACH identifies the type of the target system and insert MACH into the line beginning with MACHTYPE= in the top level Makefile. If you have to use your own implementation of alloca(), move it to src/alloca.s.MACH. Otherwise create an empty src/alloca.s.MACH. 2) Find a predefined C preprocessor symbol that identifies your target environment (such as is68k, vax, i386, etc.); if you can't find such a symbol, invent one and define it in the top level Makefile's CFLAGS by means of the -D option. Put the relevant #define statements for the target environment into the configuration file src/config.h; enclose the group of definitions by #ifdef XYZ ... #endif where XYZ is the symbol identifying the type of environment. You may want to look at the definitions for the already supported environments in the same file. One or more of the following symbols can be #defined: VFORK indicates that your system has the vfork() library function. fork() will be used if VFORK is undefined. Define VPRINTF to indicate that your system has the vprintf() library function. If VPRINTF is undefined, vprintf() will be simulated by means of _doprnt(). If your system provides neither vprintf() nor _doprnt(), you will have to modify the relevant parts of src/print.c. BIG_ENDIAN indicates that your system is of type "big endian" (most significant bit first). "Least significant bit first" (LITTLE_ENDIAN) will be assumed if BIG_ENDIAN is undefined. TIME_H should hold the location of the system include file time.h. This usually is either or . DIRENT indicates that the readdir() library function returns a pointer to a "struct dirent" and requires the include file . If DIRENT is undefined, readdir() will be assumed to return a pointer to a "struct direct" and will be included. TERMIO indicates that your system supports the "termio" terminal interface and ioctl commands. If TERMIO is undefined, the BSD-style interface will be used instead. Define UNISTD to indicate that usage of access() requires the file to be included. If UNISTD is undefined, it will be assumed that the relevant constants are defined in . If USE_SIGNAL is defined, signal() will be used instead of sigblock() and sigsetmask() to block and re-enable signals. If the target system does not provide the BSD-style getrlimit() function to obtain the maximum size of the process's stack segment, STACK_SIZE can be defined to hold the maximum stack size as a constant (a reasonable value for STACK_SIZE is 512 KBytes). However, if your system provides a different function to obtain the maximum stack size, you should modify the function Get_Stack_Limit() in src/main.c accordingly. If your system does not provide the BSD-style getdtablesize() function, MAX_OFILES should indicate the maximum number of open files for a process. If there is no fchmod() library function on your system, define FCHMOD_BROKEN. In this case chmod() will be used instead. Dynamic loading: Define CAN_LOAD_OBJ if the target system enables dynamic loading of object files. This requires that the system linker (/bin/ld) supports the -A and -T options for incremental loading and that the data space in the interpreter is executable, i.e. that it is possible to derive a function pointer to an object that has been loaded into data space. In addition, it requires that your system supports the BSD-style a.out format; the current release of the software does not support dynamic loading for other a.out file formats (such as COFF). In addition to CAN_LOAD_OBJ you should define XFLAG_BROKEN if the system linker is broken so that the -x option cannot be used together with -A. This is true for certain releases of SunOS. If dynamic loading is not supported, you should define the symbol INIT_OBJECTS to instruct the interpreter to initialize statically linked extensions on startup. See also point 6) of INSTALLING THE SOFTWARE above. Dumping: Define the symbol CAN_DUMP if the target environment allows to create an executable file from a running process. Dumping requires that the a.out file format supported by the system is either the BSD-style a.out format or the COFF format. In the latter case, define the symbol COFF. If COFF is defined, it will be assumed that the "ld" library is present on your system (a collection of functions that provide access to the parts of an object file), and PAGESIZE must hold the system's page size (measured in bytes). If COFF is undefined, the symbols SEGMENT_SIZE, FILE_TEXT_START, MEM_TEXT_START, and TEXT_LENGTH_ADJ must be defined in addition to CAN_DUMP. SEGMENT_SIZE is the segment size of the system's memory management unit, i.e. the number to a multiple of which the size of an a.out segment (e.g. .text) is rounded up; FILE_TEXT_START is the file offset at which the text segment starts in an a.out file; MEM_TEXT_START is the starting address of the text segment in memory; TEXT_LENGTH_ADJ must be set to "sizeof (struct exec)" if the length of the text segment stored in the a.out header includes the a.out header itself. 3) If everything is working, send me the "diffs" and especially the new stack.s so that I'm able to incorporate your modifications into the next release of the software.