MacGIPSY


This page describes the installation of GIPSY on G4 and G5 PowerPC Macs. For instructions on installing on Intel Machines click here.





Running GIPSY on  Apple Mac G4 and G5 machines

It is possible to run the Groningen Image Processing SYstem on Apple Mac G4 and G5 systems using the method desccribed below. Now the bad news is that there is a fair amount of patching of the source code involved. This is because Mac OS X contains "the best of" various (different) UNIX flavours, and of course has its own idiosyncracies as well. GIPSY source code usually contains different options for each flavour, and choices for the most applicable options and libraries have to be made on a case-by-case basis. The Apple compilers furthermore define different macros than e.g. Linux compilers; many of the header files will have to be changed too. Until this port of GIPSY is officially supported by its developers, one should not expect things like automatic updates to work. Also, once patched do not expect the source code to be compiled under any other (non-Mac) operating system.  This particular version has been tested on a Powerbook G4, as well as a PowerMac G5 and ran without problems. This is also the place to thank Hans Terlouw from the Kapteyn Institute for his support and help.

Now the good news is that most of the patched source code can be downloaded below, and installing GIPSY should not involve more extra work than just downloading and un-tarring one extra file. Let's begin....




1. Preparations.


i) The code has been compiled on a Powerbook G4 and PowerMac G5 both running MacOSX 10.3.6, Darwin kernel version 7.6.0. You will need the g77 compiler. The version used here is based on gcc-3.4.2 and can be easily obtained using the fink and finkcommander applications (search for 'g77'). You may also have to install the Xaw3d library in order to run the GIPSY GUI applications. This can also be done with fink. The rest of these instructions assume that the fink-installed applications and libraries are installed under the /sw directory (fink's default).

ii) Download the GIPSY source code from the GIPSY Download and Installation page. Follow the instructions in the "Download the Source" section, using Method 1.
Do not yet proceed with "Installation Step 1", instead follow the instructions below.
Note that the patches described below were created using the source code that was current on 18 November 2004. More recent source codes may contain changes invalidating some patches. If you run into problems, you can, as a last resort, download the 18 Nov 2004 source code here (hosted with kind permission of the GIPSY team at the Kapteyn Institute).




2. Patching the source code
(the easy way)

The patched source code is available in this tarfile. Save it to disk, and put it in the $gip_root/import/src directory (with the original source tar file). Then run the commands

cd $gip_root
tar xzvf import/src/gipsy_macsrc.tar.gz


This will put the patched source files in their proper places. Remember that the original source files will still be available in the tar-file in $gip_root/import/src should you need them.

You should now be able to to continue with the installation as described from "Installation Step 1" and further on the GIPSY installation page. Skip the first paragraph of "Installation Step 2: Compiler Setup", as the patch already contains the correct setup file. Continue with the second paragraph and further. After that you should be able to run GIPSY.

The next section describes in detail what changes were made to the source code. In case of problems please refer to this first. Also, keep in mind that this port was only ever intended to get GIPSY up and running on the Mac. It is neither meant to be elegant, nor to conform to programming standards, nor to be optimal in any sense. So, if you have suggestions for improvement, please let me know, by sending an email to my email addressso this port can be improved.

End of Installation. If you want to know about the nuts and bolts, please read on....


Update: For Mac OS X 10.4 some additional changes may need to be made (with thanks to Martin Zwaan).

---

in gip_sub/gip_lock.c:

line 185
remove declaration of "write":
...
   int  nt = 0;                         /* total number of bytes */
   int  r = 0;                          /* return value */
   /* int       write( );*/             /* writes on socket */

   while (nl) {                         /* while still some bytes left */
...


line 211:
remove declaration of "read":
...
   int  nt = 0;                         /* total number of bytes */
   int  r = 0;                          /* return value */
   /* int       read( );*/              /* read bytes from socket */

   while (nl) {                         /* until nothing left to do */
...


in gip_sub/pgdriv.src:

thsdrv.c: line 9187:
remove declaration of "write":
...
static  void    wterm( int id, char *buf, int l )
{
   int                  unit = ths_devs[id].unit;
   /* int               write( ); */

   (void) write( unit, buf, l );
...







3. Patching the source code (what really happened....)

* First we need to tell GIPSY about the new architecure. For consistency with compiler options defined later, this new architecture will be called 'apple' and not 'darwin'. The script mkclient.csh in $gip_sys calls getarch.csh, which is the script that figures out the architecture.  In the script you will see a list of architectures. Add the following new (bold) lines near  line 39 of  getarch.csh

if ( ${?uname} ) then       # on SYSV systems this works
  switch ( `${uname}` )     # switch   
  case Darwin:
    setenv archi apple # set to apple
    breaksw   # break
  case AIX:       # IBM/AIX
    setenv archi aix    # set to 'aix'



* Next we need to define the compiler options in the $gip_loc/setup file. Some experimenting showed that the g77 compiler is most suited. The gcc compiler was tried as well, but did not do well in the C/Fortran communication.

Following are the relevant lines from the Mac setup file:
apple:\
g77:\
-D__g77__=2 -O2 -I. -I$gip_inc -I- -I/usr/include -ansi -pedantic -w:\
-D__g77__=2 -O2 -I. -I$gip_inc -I- -I/usr/include -ansi -pedantic -Wall:\
$gip_lib/giplib.a -lmx:\
g77:\
-O2 -fno-backslash -fno-f2c -w:\
-O2 -fno-backslash -fno-f2c -Wall:\
$gip_lib/giplib.a -lmx:\
as -o #object #source:\
ar cq #library #object:\
ar d #library #object:\
14:\
ar d #library __.SYMDEF; ar s #library:\
nm #object:\
-I/usr/X11R6/include -I/usr/X11R6/include/X11:\
-L/usr/X11R6/lib/ -lX11:\
-L/usr/X11R6/lib -L/sw/lib/ -lXaw3d -lXmu -lXt -lXext -lSM -lICE -lX11

Note the inclusion of the -L/sw/lib switch in the last line, this is to make the Xaw3d library (from fink) visible.  The -lmx  switch refers to Apple's extended math library.



* Some operating system dependent variables need to be set in $gip_inc/osdef.h. Add the following lines somewhere in the middle. The __APPLE__ macro is built in the compiler, and lets the program know it is dealing with an Apple Mac machine. The other macros do not necessarily correspond with the architecture (Mac OS X is not entirely BSD for example), but they are needed to compile the code.

#if defined(APPLE) | defined(__APPLE__)

#ifndef __APPLE__
#define __APPLE__
#endif
#define OS_ARCHITECTURE   "apple"   /* APPLE */
#define OS_FLOATING_TYPE  0   /* IEEE Big_Endian */
#define OS_INTEGER_TYPE   0   /* Big_Endian */
#ifndef __bsd__
#define __bsd__
#endif
#ifndef __unix__
#define __unix__
#endif
#ifdef  __GNUC__
#ifndef __F2C__
#define __F2C__
#endif
#endif
#endif




* The apple architecture needs to be added to the $gip_sys/mkbookkeeper.csh file. On line 52 add 'apple'
#
# Now put in the known architectures
#
echo 'aix:alliant:alpha:apple:convex:cray:hp9000s300:hp9000s700:linux:mips:sgi:sol4:sun4:sun386i' >> bookkeeper.new
#



* Libraries and xclib.c

GIPSY has its own version of the standard C libraries (stdlib, stdio, stddef, etc), developed many years ago when many compilers did not yet follow the ANSI C standard. These days the Mac OS X compilers are fully ANSI compliant, and there is no reason not to use the system libraries. Also, in many cases the functions defined in the GIPSY libraries have a different type from the system versions, leading to all sorts of conflicts. The system versions are therefore preferred.

This means that the following libraries have been replaced by versions that simply call the system version. For example, $gip_inc/stdio.h now simply contains the line "#include <stdio.h>" and not much else. In order to not have to rewrite most of the #include statements we keep including the versions in $gip_inc, even if all they do is include the system versions in turn.
The following libraries have been replaced:

string.h
signal.h
stdio.h
stdlib.h
limits.h
errno.h
stddef.h
math.h
float.h
ctype.h
stdarg.h
time.h

Also note that $gip_sub/xclib.c is therefore no longer needed. The macro __xclib__ in $gip_sub/xclib.c which determines whether it gets compiled or not has therefore been disabled for the __APPLE__ case. The inclusion of $gip_sub/xclib.c can be removed without harm from the $gip_sys/install.csh file, but as to not do any more harm than necessary it is left in for now.

$gip_sub/xclib.c
Near line 140, add __APPLE__ option
...
#elif defined(__vms__)        /* DEC VMS */
#define __xclib__
#elif defined(__APPLE__)        /* APPLE */
#if defined(__xclib__)
#undef  __xclib__           /* should already be undef, but just in case */
#endif
#endif

/*
 * Here we check whether we have anything to compile.
 */

...



* Miscellaneous changes

$gip_tsk/timer.c
This task has options for BSD (__bsd__) and System 5 (__sysv__) types of systems. Normally we would pick up the __bsd__ option, except here. The BSD case calls a function ftime() which is not supported by Apple. We have to use the SysV version therefore (which does work).
Everywhere replace __sysv__ with __APPLE__, and __bsd__ with __bogus__. The latter macro does not exist, just to make sure it doesn't get picked up by the compiler.

From line 65:
...
#if defined(__APPLE__)
  
#include  <sys/time.h>

#elif defined(__bogus__) 
  
#define   ftime FTIME
...

From line 90:
...
#if defined(__APPLE__)

   struct timeval   Tp;
   struct timezone  Tzp;
#elif defined(__bogus__)
   struct timeb tr;       /* struct from ftime */

...
From line 99:
...
#if defined(__APPLE__)

   gettimeofday( &Tp, &Tzp );     /* get timeofday */
   rt = (double) Tp.tv_sec + 0.000001 * (double) Tp.tv_usec;
#elif defined(__bogus__)
   ftime( &tr );        /* get real time */

...

$gip_tsk/sheltran.src:
The sheltran code contains code for unix systems and VMS systems; A UNIX or VMS switch is used to compile the correct code. Unfortunately, it is not trivial to pass an argument to a sheltran program, and in this case the IF UNIX ... line was removed, as well as the entire VMS section, so that sheltran is always compiled as the unix variety.

$gip_sys/cshrc.csh
On line 35 gip_root needs to be between '{}' brackets

# Initialize the GIPSY environment
#
source ${gip_root}/sys/gipenv.csh               # setup the gipsy environment
#

$gip_sub/gip_lock.c
The sleep() function is not defined in the headers that are included. Add the unistd.h header file to the list of header files around line 92.

...
#include  "xscanf.h"      /* read devces file *
#include  <unistd.h>

#define GLOCK_CONNECT     1 /* connection made */
...


$gip_sub/axprops.c
Include the string.h library to declare strcpy() function.

#include "string.h"


$gip_tsk/hermes.src

Many changes here.
The termio.h header file included by hermes is no longer supported, and has been replaced with the termios.h file. In the hermes.src file, this is relevant in the first few lines of the source code for terminal.c. Here the variable USE_TERMIOS is used to point to the termios.h file, as well as the sys/ioctl.h file. The latter used to be included in termio.h, but is not in termios.h, hence the separate include.

hermes.src --> terminal.c
#include "stddef.h"   
#include "terminal.h"
#if defined(__aix__) | defined(__sgi__) | defined(__linux__) |defined(__APPLE__)
#define USE_TERMIOS  
#endif
...
#if defined(USE_TERMIOS)
#include <termios.h> 
#include <sys/ioctl.h>
...

The structs that are defined a few lines down must be of type termios and no longer termio.
...
#if defined(USE_TERMIOS)
static struct termios tt;
static struct termios ttorg;

...
A few lines down again, in the case HERTERM, the ioctl arguments TCGETA and TCSETA are now called TIOGET and TIOSET and need to be replaced (alternatively the source can be adapted to use the __mips__ option). Furthermore the new ioctl struct does not contain the c_line component. This needs to be removed (as in tt.c_line). This has (as far as can be made out) no effect on the code.

...
      case HERTERM:               /* set tHermes terminal characteristics */
#if defined(USE_TERMIOS)
   ioctl(0,TIOCGETA,&ttorg);
   tt.c_iflag = 0;
   tt.c_oflag = 0;
   tt.c_cflag = ttorg.c_cflag; /* tt.c_line removed here */
   tt.c_lflag = 0;
   tt.c_cc[VMIN] = 1;
   tt.c_cc[VTIME] = 0;
   ioctl(0,TIOCSETA,&tt);
...

It is no longer necessary to include getdtablesize() in the hermes.src file, as this is now a standard system library that is included in unistd.h. In hermes.src this file is only included if the __sysv__ macro is true. In all cases this  #ifdef __sysv__, ..., #endif  clause needs to be removed  so that  unistd.h is always included.
getdtablesize.c must thus be removed from hermes.src (also for reasons of conflicting types). Do not forget to remove getdtablesize.c and getdtablesize.o from the Makefile (top) part of the source file.

Lines 220-221, 232-233, 251-252, 256-257, 261-262, 266-267:  add -ltermlib after $(OBJECTS) to link to system library (because of the definitions in termios.h).

Near line 13725, add __APPLE__ option
...
#if defined(__linux__) | defined(__APPLE__)
#define speed_t unsigned int
#endif
#include "stddef.h"
...
Near line 14874, add __APPLE__ option
...
#if defined(__linux__) && !defined(__USE_BSD)

#define __USE_BSD
#endif
#if defined(__APPLE__) && !defined(__USE_BSD)
#define __USE_BSD
#endif

...

$gip_tsk/coder.c, $gip_tsk/print.c

Declaration of static bool toascii duplicates system function (but with different type). As this is a local function simply rename to toasciiz everywhere (i.e. static bool toasciiz; toasciiz = tobool(NO); etc.).

$gip_tsk/dssload.c, $gip_tsk/gdsserver.src, $gip_tsk/plserver.src
Declaration of float bzero or int bzero duplicates system function bzero(). Replace with b_zero everywhere.

$gip_tsk/gplot.src
strdup() already declared in system libraries. Remove declaration as well as definition of char *strdup(char *).

$gip_tsk/gdsserver.src, $gip_tsk/hermes.src, $gip_tsk/htmldoc.src
Need to explicitly define the system version of the lseek() function. Add #include <unistd.h> to every source code unit that contain the lseek() call.

$gip_tsk/compile.c
Need to add __APPLE__ definition for extern int fileno(FILE *) (line 505 of compile.c)
...
#elif defined(__linux__)
extern  int fileno(FILE *);
#elif defined(__APPLE__)
extern  int fileno(FILE *);
#else
#define fileno(p) ((p)->_file)

...

Near line 517, add __APPLE__ option to definition of extern char *getcwd(char *path, int size)
...
#if defined(__sysv__) | defined(__linux__) | defined(__APPLE__)
extern  char    *getcwd( char *path, int size );
#endif

...

Near line 544, add __APPLE__ option
...
#if defined(__linux__) | defined(__APPLE__)
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
 *

...

Near line 5977, add __APPLE__  option
...
static  int cleantmp( void )

   DIR      *dirp;
#if     defined(__sysv__) | defined(__linux__) | defined(__APPLE__)
   struct dirent  *dp;      /* directory entry pointer */

...

Near line 6028, add __APPLE__  option
...
   parent *p = dummy3;
#if     defined(__sysv__) | defined(__linux__) | defined(__APPLE__)
   struct dirent *dp;                           /* directory entry pointer */
#else
...

Near line 6633, add __APPLE__  option
...
#if defined(__bsd__)      /* BSD */
      pwd = getwd( cwd );     /* pwd */
#endif
#if defined(__sysv__) | defined(__linux__) | defined(__APPLE__)     /* SYSV */
      pwd = getcwd( cwd, FILENAME_MAX );  /* pwd */

...

$gip_tsk/report.c
Line 71,
add __APPLE__  option, to call unistd.h
#if defined(__linux__) | defined(__APPLE__)
#include    <unistd.h>
#endif


Line 71, add __APPLE__  option to avoid redefining access() (defined in system library)
...
#if !defined(__APPLE__)

extern   int   access( char *path, int amode );
#endif

...

Line 182, add __APPLE__  option to avoid redefining uid_t() (defined in system library)
...
#if !defined(__linux__) | !defined(__APPLE__)

extern  uid_t           getuid( void );  
#endif

...

$gip_tsk/f2cvv.c
near line 151, add  __APPLE__ option
...
#if defined(__g77__) | defined(__linux__) | defined(__FreeBSD__) | defined (__APPLE__)
...

Near line 420, add __APPLE__ option. Replace int by long.
...
fprintf( f, "\n#if defined(__g77__)| defined(__F2C__)|defined(__linux__) |defined(__APPLE__)
fprintf( f, "\ntypedef long fint;" );
fprintf( f, "\ntypedef long bool;" );
...

$gip_tsk/gids.src
Line 860, add __APPLE__ options
...
extern  int fileno(FILE *);

#elif defined(__linux__)
#elif defined(__APPLE__)
#else

...


Subroutines

Replace __unix__ by __APPLE__ in
flist.c
fsize.c
ftrunc.c
gdilib.c
getlognam.c
getusernam.c
irserver.c
mtiodev.c
pgdriv.src
xclib.c

$gip_sub/gds___server.c
Lines 25 and 259, add __APPLE__ option
 #if defined(__linux__) | defined(__APPLE__)

$gip_sub/gdsi_read.c
line 32: add #include <unistd.h>
Use the system versions for file open/write/etc: comment out following near line 70
...
/* extern int close( );   unix close */
/* extern int fsync( );    unix synchronization */
/*  extern  int lseek( );    unix seek */
/* extern int open( );     unix open */  
/*   extern int read( );     unix read */
/*  extern  int write( );    unix write */

...

$gip_sub/ggi.src
near line 8646, add #include <unistd.h>

$gip_sub/gip_lock.c
near line 92, add #include <unistd.h>

$gip_sub/ircc_const.c
Definition of strnstr() on line 68 conflicts with system definition. As this is only used locally rename to strzstr() everywhere within this subroutine.
 static char *strzstr( char*, fint, char * ) ;
etc

$gip_sub/irserver.c
Line 62, add #include <stddef.h>
Line 511, definition of
NULL used here conflicts with definition used elsewhere. Rename index to indexz everywhere in this routine. E.g. static FILE * indexz = NULL ; etc

$gip_sub/pgdriv.src
Near line 9117, add #include <unistd.h>

near line 10510, add __APPLE__ option
...
#if !defined(__linux__)

#include  <sgtty.h>
#endif

#if !defined(__APPLE__)
#include  <sgtty.h>
#endif

...

$gip_sub/textfield.src
Near line 60, add #include <wchar.h> and #include <stdlib.h>


Erwin de Blok, my email,18/Nov/2004