[net.unix] "am I a vax" commands

guy@sun.UUCP (05/05/86)

> The "proper" way to do this is by testing `uname -m`.

Well, "uname" isn't on all machines, so it's only the proper way on S5 (not
V7, 4BSD, or S3).

Besides, as you point out, there are no standards on what "uname -m" should
return.  One problem here is that on my machine, for instance, there are
*four* different possible answers:

	1) it has a Motorola 68000-family chip as its CPU, so it should
	   be something like "m68k";

	2) it has a Motorola 68020 as its CPU, so it should be something
	   like "M68020";

	3) it is a Sun, so it should be something like "sun";

	4) it is a Sun-3, so it should be something like "sun-3".

As such, unless AT&T-IS is going to change the layout of the "uname"
structure to include several more fields (which is extremely unlikely),
"uname" isn't the right answer.

Furthermore, the Makefile for VAX S5R2 sets things up so that "uname -m"
returns "vax-780"; the equivalent on my machine would be to have it return
"sun-3/50".  However, everything after the "vax" in "vax-780", and
everything after the "3" in "sun-3/50", is of minimal interest to 99 44/100%
of the software out there (the kernel cares, but it can figure out the
complete machine type at boot time).

The version of the C preprocessor that comes with the Fourth Generation Make
("nmake" from the AT&T Toolchest) has some functions for these purposes.
They have "model", "architecture", and "machine".  "model"

	Defines the hardware model or workstation name.  Example values
	for "model-name" are "apollo", "sun", "ibm-pc" and "unix-pc".

"architecture"

	Defines the processor architecture name.  Example values for
	"architecture-name" are "3b", "68000", "ibm", "pdp11", and "vax".

"machine"

	Defines the processor architecture version.  Example values for
	"architecture-version" are "2, "20", and "20s" for
	"architecture(3b)", "70" etc. for "architecture(pdp11)", and
	"750", "780", and "micro" for "architecture(vax)".

I could see the following categories:

	CPU family - general family of CPUs.  "pdp11", "vax", "m68k",
	"NS32000", etc. (unfortunately, "iAPX86" is, I think, somehow
	equivalent to "8086"; some name is needed for the 8086, 8088,
	80186, 80188, 80286, 80386, ...).

	CPU family member - "M68010", "M68020", "iAPX286", etc.

	Machine family (which would be the same as the CPU family in most
	cases of proprietary architectures) - "pdp11", "vax", "sun",
	"apollo", "power5", "power6", etc..

	Machine sub-family - "sun2", "sun3", etc..  I'm not sure whether this
	is necessary or not.  The "sun2"/"sun3" example might not make
	it necessary; one could treat "sun2" and "sun3" as separate
	"machine families" and do anything Sun-dependent if it's "sun2"
	or "sun3".

	Specific machine - "pdp11/74", "vax-780", etc..  If this is
	useful at all, it might be subsumed under "CPU sub-family".

Unfortunately, the AT&T 3B machines really throw a bit of a monkey wrench into
this.  The 3B1 has a Motorola 68010 chip; the 3B<n>, for <n> != 20, have a
WE32000 series chip; the 3B20 has a proprietary CPU which is close to the
WE32k at the assembly-language level, but not at the machine-language level.
I'm sure other systems create similar pathologies.

In some cases, this stuff is used to identify peculiarities of the UNIX
implementation, rather than of the machine.  If this would complicate any of
this, the answer is to take another leaf from that "cpp"s book and have a
separate command to indicate the particular flavor of UNIX.  This, of
course, has its own complications; do you just identify the general UNIX
family (if so, what is the S5-based Xenix?  Is it "xenix-5" or whatever
Microsoft calls it, or is it "system5", or what?  What about a system which
offers both 4BSD and S5 features?), or do you identify the system by what
the vendor calls it (in which case, it's a pain to construct predicates
which say "where are mailboxes kept" or "does this have S5 IPC" or...).

> N.B. The same machine type should be pre#defined by CPP.

I sort of agree, except that pre#defining names causes all sorts of
problems; in effect, arbitrary portions of your name space can be hijacked
by vendors in the future.  The "function" approach of the Fourth Generation
Make's "cpp" seems better; you say

	#if architecture(vax)

instead of

	#if vax

If there is a function of this sort named "foo", there should be a command
"foo" such that if the function "foo(X)" is true, the "foo" command should
print "X" on its standard output.

Of course, one reason for using these #defines is to ask questions like
"what's the byte order on this machine"; using these #defines is a pain
because your code won't be prepared to deal with arbitrary new machines.  It
might be better to define something like "BIG_ENDIAN" or "LITTLE_ENDIAN" in
some standard #include file, and insist that vendors put this into their
standard copy of this #include file.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/06/86)

Greg and Guy have made some good points.  I agree that the current
situation is inadequate in general; there is NO good universal way
to determine target system specifics at "make" or compile time.

This makes it even more important to avoid system dependencies in
code that is targeted to be used on a variety of systems.  There
are some cases where one simply has to take machine architecture
into account, but the vast majority of such applications need not
do so, and many others can be structured so that system-specific
code is limited to a small handful of common interface modules.
This approach, coupled with widespread adoption of language and
environment standards, makes porting much less painful than usual.