[comp.unix.ultrix] Distinguishing "true" MIPS box from DECstation at compile time

bin@primate.wisc.edu (Brain in Neutral) (12/16/89)

How does one tell, when compiling a C program, whether the host is a
true MIPS machine (e.g., M/120) from a DECstation that's running
Ultrix.  I think I remember reading an article a while back that
complained about "mips" being defined by the preprocessor even on
Ultrix machines.  Is this true?  If so, is the test

# if mips
# if ultrix
	DECstation
# else
	true MIPS
# endif
# endif

Is there a nicer way?

Yours,
Paul DuBois
dubois@primate.wisc.edu

moraes@cs.toronto.edu (Mark Moraes) (12/16/89)

bin@primate.wisc.edu (Brain in Neutral) writes:
># if mips
># if ultrix
>	DECstation
># else
>	true MIPS
># endif
># endif

Not so fast. SGI also defines "mips" on the Iris4D machines -- why
not, it's the CPU they use.

One possible solution, seen to work on our Iris4D (Irix3.2), our
DS3100s (Ultrix3.1), and our M/120 (Riscos4.0:

#ifdef mips
# ifdef ultrix
#  define ULTRIX_MIPS
#  define arch "ultrix-mips"
# endif
# ifdef sgi
#  define IRIS4D
#  define arch "iris4d"
# endif
# ifndef arch
   /*
    * Must be MIPSCo MIPS. Anyone know a way to differentiate between
    * RISCOS4.0 and UMIPS via cpp?
    */
#  define MIPS
#  define arch "mips"
# endif
#endif

Then one can use the symbols MIPS, IRIS4D, or ULTRIX_MIPS.

Note: this will presumably change once vendors start shipping truly
ANSI compatible compilers -- ANSI prohibits this sort of random
pollution of the namespace. (It'll be __mips__ or suchlike, and life
will become even more complicated, as people try to keep code
backwards compatible with things like"#if defined(mips) ||
defined(__mips__)"))

Another solution is to stick a wrapper script around cc, and get it to
define the symbols you want. The shell script I use for our SGI
machines is enclosed below.

*Soapbox on*

It is probably much better to ifdef on specific features that one
needs (eg.  BSD_SIGNALS, JOB_CONTROL, DIRENT, SHMEM, etc) than on a
specific vendor type, considering the way the zillion and one
"standard" deviants, er, variants, of Un*x are growing warts, er,
features. Relying on even the vendors operating system remaining the
same is probably not portable. As for the simple distinction between
BSD and SYSV, that's gone a long time ago, thanks to extensive
cross-breeding...

Then one can create configuration headers per machine -- s-machine.h,
sysdep.h, whatever, defining specific features on a per release basis,
as is sometimes necessary :-( The joys of maintaining a single source
tree for multiple architectures and OS deviants!

*Soapbox off*

#! /bin/sh -
# Fake CC driver that includes local and bsd stuff and links compatibility
# bsd routines. Also defines __iris4d__ and __irix__, as well
# as linking in /local/lib libraries before system defaults.
# Also munges output error messages from cc to BSD format, so it can
# be automatically parsed by Jove.
# Mark Moraes, University of Toronto
realcc=/usr/bin/cc
includes=
args=
for i
do
	case "$i" in
	-I*) includes="$includes $i";;
	-v) set -x;;
	esac
done
includes="$includes -I/local/include -I/usr/include/bsd"
tmp=/tmp/cc.bsd.$$
trap 'rm -f $tmp; exit $status' 0
$realcc -D__iris4d__ -D__irix__ $includes -L/local/lib "$@" -lbsd 2> $tmp
status=$?
# Postprocess errors - cc can produce stuff on stdout, for cc -M, f'rinstance
sed 's/^[^:]*: \([^:]*: \)\([^,]*\), \([^:]*: \)\(.*\)/"\2", \3\1\4/' $tmp >&2

treese@crltrx.crl.dec.com (Win Treese) (12/16/89)

In article <1300@uakari.primate.wisc.edu> bin@primate.wisc.edu (Brain in Neutral) writes:
>How does one tell, when compiling a C program, whether the host is a
>true MIPS machine (e.g., M/120) from a DECstation that's running
>Ultrix.  I think I remember reading an article a while back that
>complained about "mips" being defined by the preprocessor even on
>Ultrix machines.  Is this true?  If so, is the test

According to the Ultrix/RISC manual page for cc, the following symbols
are defined (may change when ANSI C rolls around):

     unix           Any UNIX system
     bsd4_2         Berkeley UNIX Version 4.2
     ultrix         ULTRIX only
     mips           Any MIPS architecture
     MIPSEL         Little endian variant of MIPS architecture
     host_mips      Native compilation environment (as opposed to
                    cross-compiler)

If I'm being specific to Digital's RISC machines, I'd use

#if defined(mips) && defined(ultrix)
#endif

Actually, I'd probably stuff that kind of thing into machine/system-specific
configuration files and #ifdef based on feature.

Win Treese						Cambridge Research Lab
treese@crl.dec.com					Digital Equipment Corp.

msc@ramoth.esd.sgi.com (Mark Callow) (12/19/89)

In article <89Dec15.145750est.2273@neat.cs.toronto.edu>,
moraes@cs.toronto.edu (Mark Moraes) writes:
> 
> *Soapbox on*
> 
> It is probably much better to ifdef on specific features that one
> needs (eg.  BSD_SIGNALS, JOB_CONTROL, DIRENT, SHMEM, etc) than on a
> specific vendor type, considering the way the zillion and one
> "standard" deviants, er, variants, of Un*x are growing warts, er,
> features. Relying on even the vendors operating system remaining the
> same is probably not portable. As for the simple distinction between
> BSD and SYSV, that's gone a long time ago, thanks to extensive
> cross-breeding...
> 
> Then one can create configuration headers per machine -- s-machine.h,
> sysdep.h, whatever, defining specific features on a per release basis,
> as is sometimes necessary :-( The joys of maintaining a single source
> tree for multiple architectures and OS deviants!
> 
> *Soapbox off*

Yes, Yes,a thousand times yes.

Even though the system vendors don't define "feature ifdefs" you can write
your code as if you had them.  You simply have to create a header that does
all the ugly stuff (like that in the rest of the referenced article) and
sets the appropriate "featuredefs".

We tried to persuade the X consortium to change the ifdef's in X to a scheme
like this.  Their response was lukewarm.

yar@cs.su.oz (Ray Loyzaga) (12/21/89)

In article <2103@odin.SGI.COM> msc@sgi.com writes:
> In article <89Dec15.145750est.2273@neat.cs.toronto.edu>,
> moraes@cs.toronto.edu (Mark Moraes) writes:
> > It is probably much better to ifdef on specific features that one
> > needs (eg.  BSD_SIGNALS, JOB_CONTROL, DIRENT, SHMEM, etc) than on a
> > specific vendor type, considering the way the zillion and one
> > [Deleted]
> > Then one can create configuration headers per machine -- s-machine.h,
> > sysdep.h, whatever, defining specific features on a per release basis,
> > as is sometimes necessary :-( The joys of maintaining a single source
> > tree for multiple architectures and OS deviants!
> > 
> > *Soapbox off*
> 
> Yes, Yes,a thousand times yes.
> 
> Even though the system vendors don't define "feature ifdefs" you can write
> your code as if you had them.  You simply have to create a header that does
> all the ugly stuff (like that in the rest of the referenced article) and
> sets the appropriate "featuredefs".

> We tried to persuade the X consortium to change the ifdef's in X to a scheme
> like this.  Their response was lukewarm.

The only problem with this approach is that all the sources that you develop
will have #includes of files that are not available on any other system,
you could #ifdef the includes but on the basis of what? The bottom line
is that you need to have an "include" file that defines the way the system
is set up, and this file is sourced by cpp with every invocation.
This file should contain the "standard defines" such as mips or sysV etc,
these are currently compiled into cpp or a caller program and mean that
the user must rely on the result of the output of "strings" on cpp or cc,
and some guesswork, or hope that any changes are reflected in the
manuals on each release. I'd be much more comfortable in reading a file
such as /etc/local-system which contains
-Dmips
-DBSD4

etc, and having cpp doing something like
#!/bin/sh
/lib/cpp.real `cat /etc/local-system` "$@"

The inbuilt defines couldn't be clearer and there would be no need to
include any files that are unlikely to exist on other machines.
We currently use such a system to communicate some kernel changes
that affect the sizes of system structures to all the system
sources without having to edit them.

lamaster@ames.arc.nasa.gov (Hugh LaMaster) (12/22/89)

In article <2103@odin.SGI.COM> msc@sgi.com writes:
>In article <89Dec15.145750est.2273@neat.cs.toronto.edu>,
>Even though the system vendors don't define "feature ifdefs" you can write
>your code as if you had them.  You simply have to create a header that does
>all the ugly stuff (like that in the rest of the referenced article) and
>sets the appropriate "featuredefs".

I agree with most of what is written here, but, I sure could use a standard
way to determine from the shell what architecture of machine I am on.

I wish, for example, that the "arch" command could be made universal, and
would return a string which has 2 simple components.  For example:

sun3
sun4

decvax
decmips

sgimips

(or whatever you want, as long as it is unique).

BTW, I currently use if [] tests on files to guess,  when something
else is not available, but this doesn't work
reliably because of differences in filesystem mounts, which optional 
software is loaded, etc.


  Hugh LaMaster, m/s 233-9,  UUCP ames!lamaster
  NASA Ames Research Center  ARPA lamaster@ames.arc.nasa.gov
  Moffett Field, CA 94035     
  Phone:  (415)694-6117       

casey@gauss.llnl.gov (Casey Leedom) (12/24/89)

| From: moraes@cs.toronto.edu (Mark Moraes)
| 
| It is probably much better to ifdef on specific features that one needs
| (eg.  BSD_SIGNALS, JOB_CONTROL, DIRENT, SHMEM, etc) than on a specific
| vendor type ...

  I agree, but if you do this, please use the proposed POSIX defines for
this.  That way you shouldn't have to change too much when POSIX actually
makes it out of the shop.  (Sorry, I don't have the draft standard on me,
so I can't provide any details on what the proposed defines are or even
which file a POSIX conforming program is supposed to include to get the
set of Supported Feature Constants.)

Casey