[comp.sys.hp] problems with make

wohler@coco0.istc.sri.com (Bill Wohler) (05/04/88)

  the hp9000s350 running 6.01 chokes on the following makefile
  fragment:

	$(LIBRARY):	$(OBJS)
			@echo -n "Loading $(LIBRARY) ... "
			@ar cru $(LIBRARY) $(OBJS)
			if [ "$(SYS)" != hp ]; then \
				ranlib $(LIBRARY); \
			fi
			@echo "done"

  my sun produces [newlines inserted for clarity]:

	% make SYS=hp
	Loading lib.a ... 
	if [ "hp" != hp ]; then \
		ranlib lib.a; \
	fi
	done

  but the hp spits out:

	% make SYS=hp
	Loading lib.a ...
	if [ "hp" != hp ]; then \
		ranlib lib.a; \
	fi
	Missing ].
	*** Error code 1

	Stop.

  but it's not the hp shell:

	$ if [ "hp" != hp ]; then ranlib lib.a; fi
	$ 

  note that i've had to create these "if" fragments to "script around"
  the way that hp deals with ar, ranlib and install.  the very polite
  ranlib message about ar already producing the SYMTAB should be
  suppressed and the install command is completely changed so that we
  need to use this thing called cpset.  when is using hp-ux going to
  become a pleasurable experience?

						--bw

bd@hpsemc.HP.COM (bob desinger) (05/11/88)

>   the hp9000s350 running 6.01 chokes on the following makefile fragment:
> 	$(LIBRARY):	$(OBJS)
> 			@echo -n "Loading $(LIBRARY) ... "
> 			@ar cru $(LIBRARY) $(OBJS)
> 			if [ "$(SYS)" != hp ]; then \
> 				ranlib $(LIBRARY); \
> 			fi
> 			@echo "done"
> the hp spits out:
> 	Missing ].
> 	*** Error code 1
> 	Stop.
>
>   note that i've had to create these "if" fragments to "script around"
>   the way that hp deals with ar, ranlib and install.

As a workaround, can you use a `test' construct to replace the `if'
with a one-liner?  Something to the effect of:

	test "$(SYS)" != hp && ranlib $(LIBRARY)

Another way to test what system you're on is to use the SVID programs
documented under machid(1).  The makefile would look something like:

	hp9000s300 || ranlib $(LIBRARY)

Be sure to use the `||' form instead of the `&&'; make will screech to
a halt if you use `&&' with a system that you're not on.

I doubt if the Sun has these System-V files, but you can create them
with the commands:

	cd /usr/local		# or wherever your Sun likes local stuff
	echo "exit 1" >hp9000s300	# return false
	chmod +x hp9000s300

Do a similar thing on your HP machine, except call the file "sun," for
future reference.

Here's yet another workaround.  It makes the makefile a little easier
to read, and you don't need to say "SYS=hp" or "SYS=sun" on the make
command line.  At the top of the makefile, put these three lines:

	  # Do conditional compilation from make's shell
	  IFHP	= test ! -f /hp-ux ||
	  IFSUN	= test ! -f /vmunix ||

Then write your target and rules to look something like:

	$(LIBRARY):
		$(IFHP) echo No need for ranlib
		$(IFSUN) ranlib $(LIBRARY)
		@echo "done"

This examines your kernel file to determine which system you're on.

>   the very polite
>   ranlib message about ar already producing the SYMTAB should be
>   suppressed and the install command is completely changed so that we
>   need to use this thing called cpset.

You can fix ranlib's wagon.  Get into a directory in your $PATH that's
before the one where ranlib lives:

	cd /usr/local		# or wherever
	echo 'exit 0' >ranlib	# ranlib always returns success
	chmod +x ranlib

Voila.  Ranlib for System V.  Now you can eliminate those `if'
statements from your makefiles.

I don't know where the HP `install' command came from---is it from
System V release 2?  This is from J. E. Lapin's book "Portable C and
Unix System Programming" (Prentice-Hall, 1987):

	install:
	This utility (supported on System III, System V release 1,
	and System V release 2) is one of the rare cases where
	features present in System V release 1 have been dropped from
	an otherwise compatible System V release 2 version.  The
	System V release 2 version is identical to System III.

The accompanying table shows that AT&T dropped the -g, -m, and -u
options from the SysV.2 version.

By the way, your original makefile fragment works correctly on my
hp9000s800 (running 2.0).

-- bd

vitale@hpcupt1.HP.COM (Phil Vitale) (05/12/88)

>  the hp9000s350 running 6.01 chokes on the following makefile
>  fragment:
>
>	$(LIBRARY):	$(OBJS)
>			@echo -n "Loading $(LIBRARY) ... "
>			@ar cru $(LIBRARY) $(OBJS)
>			if [ "$(SYS)" != hp ]; then \
>				ranlib $(LIBRARY); \
>			fi
>			@echo "done"

Try inserting the following line at the top of your makefile,
and let us know how it works:

SHELL=/bin/sh

I've tested your fragment on a s800 with this fix, and it seems to do
what was expected.  (Sorry, I do not have access to a s300 at the moment.)

Phil Vitale
vitale%hpperf1@hplabs.HP.COM

wohler@spam.istc.sri.com (Bill Wohler) (05/12/88)

In article <1250004@hpsemc.HP.COM> bd@hpsemc.HP.COM (bob desinger) writes:
>>   the hp9000s350 running 6.01 chokes on the following makefile fragment:

  [deleted]

>> the hp spits out:
>> 	Missing ].
>> 	*** Error code 1
>> 	Stop.

  turned out that the hp (system v?) make actually uses any shell to
  run your commands.  adding SHELL=/bin/sh to the makefile makes it
  work for both our systems.  thanks bob.

>As a workaround, can you use a `test' construct to replace the `if'
>with a one-liner?  Something to the effect of:
>
>	test "$(SYS)" != hp && ranlib $(LIBRARY)

  much cleaner.

>I doubt if the Sun has these System-V files, but you can create them
>with the commands:

  our makefiles also have to run on suns and hps all over the country
  and in europe.  no, i don't want to make this file everywhere.
  
>	  # Do conditional compilation from make's shell
>	  IFHP	= test ! -f /hp-ux ||
>	  IFSUN	= test ! -f /vmunix ||

  i like this a lot.  you can also get more refined by not looking at
  the kernel, but rather:

	IFHP300 = test ! -f /bin/hp9000s300
	IFSUN3 = test ! -f /bin/sun3
	IFBSD = test ! -f /vmunix
	IFHPUX = test ! -f /hp-ux

  and so on.

>By the way, your original makefile fragment works correctly on my
>hp9000s800 (running 2.0).

  because i bet you use ksh which knows about "]".  

  since you're thinking about makefiles now, how would you accomplish
  something like

							--bw

bd@hpsemc.HP.COM (bob desinger) (05/16/88)

>   you can also get more refined by not looking at
>   the kernel, but rather:
> 	IFHP300 = test ! -f /bin/hp9000s300
> 	IFSUN3 = test ! -f /bin/sun3
> 	IFBSD = test ! -f /vmunix
> 	IFHPUX = test ! -f /hp-ux
>   and so on.

Yes, but be careful about merely checking the existence of the
programs in /bin/hp9000s*00; they're actually links to true(1) and
false(1) to return an exit status corresponding to the machine.

In other words, on the Series 300 and 800 both /bin/hp9000s300 and
/bin/hp9000s800 exist.  On the Series 300, /bin/hp9000s300 returns
true and /bin/hp9000s800 returns false.  On the Series 800,
/bin/hp9000s300 returns false and /bin/hp9000s800 returns true.

To get concrete about it, they're intended to be used in scripts as:

	/bin/hp9000s300 && echo "Here I am on my s300"
	/bin/hp9000s800 && echo "This executes on my s800"

The make command will complain about "Exit status 255" and stop
prematurely if the makefile uses them that way and the rule for the
`false' machine is executed.  (/bin/false is simply `exit 255'; cat
the file out and see.)  So you have to use them somewhat counter-
intuitively in the makefile, but it's nothing really strange for those
who have been following this newsgroup:

	# Which machine are we on?  (second version)
	IFHP300	= if hp9000s300 2>/dev/null; then
	IFHP800	= if hp9000s800 2>/dev/null; then
	IFSUN3	= if sun3 2>/dev/null; then
	
	target:
		$(IFHP300) echo Series 300; fi
		$(IFHP800) echo Series 800; fi
		$(IFSUN3) echo Sun 3; fi
		@echo Done

(The "2>/dev/null" keeps you from seeing complaints from the shell
about "sh: sun3: Command not found".)

As a matter of taste, you might prefer an extra makefile line of

	FI	= ; fi

with a cosmetic change to the target's rules:

	target:
		$(IFHP300) echo Series 300 $(FI)
		$(IFHP800) echo Series 800 $(FI)
		$(IFSUN3) echo Sun 3 $(FI)
		@echo Done

However you prefer the appearance, this solution gives you finer
control over your makes.  I like this solution better because it's the
cleanest so far.  (I wrote the earlier hack of peering at the kernels
because I didn't know that Sun offered /bin/sun3.  But since they do,
it's better to use the tools provided.)


>>By the way, your original makefile fragment works correctly on my
>>hp9000s800 (running 2.0).
>   because i bet you use ksh which knows about "]".  

Caught in the act!


>   since you're thinking about makefiles now, how would you accomplish
>   something like
>
> 							--bw

Could you repost that last fragment again?  The above four lines are
all I found on my machine.

-- bd

bd@hpsemc.HP.COM (bob desinger) (05/24/88)

Steve DeJarnett (steve@polyslo.UUCP) writes:
> 	Of course, if you are 'blessed' with having an HP-9000/500, this 
> won't work at all, since there is no /hp-ux (or anything of the sort).

You're right about the lack of kernel on the s500; all the more reason
to use the /bin/hp9000s*00 programs:

	# Which machine are we on?  (second version)
	IFHP300	= if hp9000s300 2>/dev/null; then
	IFHP500	= if hp9000s500 2>/dev/null; then
	IFHP800	= if hp9000s800 2>/dev/null; then
	IFSUN3	= if sun3 2>/dev/null; then

-- bd

scott@grlab.UUCP (Scott Blachowicz) (05/24/88)

A side note:

In using hp9000s500, hp9000s800, etc, you have to be careful about using
them in your .cshrc (or whatever). I had my .cshrc/.login doing checking
of machine type & doing different things on different machines. The
trouble was that the script's invocation would cause a new csh to be
spawned (wait, I see an infinite loop coming...) which in turn ran my
.cshrc. This makes for a very long login time. I ended up putting the
hp9000s500 check in my .login and setting a variable that I checked the
value of instead of running hp9000s500 directly.

Scott Blachowicz
USPS:  Graphicus                UUCP:    ...!hpubvwa!grlab!scott
       150 Lake Str S, #206     VoicePh: 206/828-4691
       Kirkland, WA 98033       FAX:     206/828-4236