[openssl-dev] [openssl.org #4444] [openssl-1.1.0-pre4] Make fails with "recipe for target 'depend' failed" on solaris64-x86_64

Rainer Jung via RT rt at openssl.org
Fri Mar 18 19:10:42 UTC 2016


Am 18.03.2016 um 19:33 schrieb Richard Levitte via RT:
> Vid Fre, 18 Mar 2016 kl. 18.07.31, skrev rainer.jung at kippdata.de:
>> Am 18.03.2016 um 17:49 schrieb Richard Levitte via RT:
>>> Vid Fre, 18 Mar 2016 kl. 16.34.05, skrev rainer.jung at kippdata.de:
>>>> I had the same problem. /bin/sh on Solaris does not understand the
>>>> "-
>>>> nt"
>>>> operator used in the definition of the "depend" target in the top-
>>>> level
>>>> Makefile, e.g. in line
>>>>
>>>> if [ Makefile -nt Makefile ] ...
>>>
>>> That can't be the cause, because whatever the exit code from the test
>>> is, it's
>>> "swallowed" by 'if'. A little like this is:
>>
>> If it were syntactically correct, but it isn't.
>
> You'll have to explain that to me. I just had a look here:
> https://docs.oracle.com/cd/E26502_01/html/E29030/sh-1.html:
>
>
>>>> if list ; then list elif list ; then list ; ] . . . [ else list ; ] fi
>
>>>> The list following if is executed and, if it returns a zero exit status,
> the list following the first then is executed. Otherwise, the list following
> elif is executed and, if its value is zero, the list following the next then is
> executed. Failing that, the else list is executed. If no else list or then list
> is executed, then the if command returns a zero exit status.
>
>> I added the "set -ex" and:
>>
>> % make depend
>> catdepends=false
>> + [ Makefile -nt Makefile ]
>> Makefile:172: recipe for target 'depend' failed
>> make: *** [depend] Error 1
>
> Would the following make a difference?
>
> if ( [ Makefile -nt Makefile ] 2>/dev/null || [ $$? = 1 ] ); then

Yes, that works. Works means: it correctly detects, that Solaris doesn't 
support "-nt" and adds all dependencies to the end of the Makefile.

> or perhaps using 'test' instead of '[' (and removing the ']' in that case, of
> course)?

Also works.

>> or - since there's no more real need for the catdepends variable
>
> That's an incorrect assumption. 'depend' is run as part of the larger targets,
> and on some slower systems, having the same file copying happening every time
> is quite time consuming. Checking if there's a need for all the data copying at
> all first takes down the time for the cases when the .d files haven't been
> updated since last time.

I think the variant I suggested still does that, at least in my tests. 
If there's no newer dependency, then it will not add anything to the 
Makefile, since the result of the "find" command is empty.

depend:
         @:
         @( sed -e '/^# DO NOT DELETE THIS LINE.*/,$$d' < Makefile; \
           echo '# DO NOT DELETE THIS LINE -- make depend depends on it.'; \
           echo; \
           for d in `find $(DEPS) -newer Makefile`; do \
             if [ -f $$d ]; then cat $$d; fi; \
           done ) > Makefile.new; \
         if cmp Makefile.new Makefile >/dev/null 2>&1; then \
           rm -f Makefile.new; \
         else \
          mv -f Makefile.new Makefile; \
         fi
         @:

With "no need for catdepends" I only wanted to say there's no need any 
more for first checking, then remembering the check result in the 
variable and then executing on the check result. Instead one can move 
the dependency change detection directly into the latter part as shown 
in my previous mail. It has also the benefit of only adding the 
dependency snippets that are newer than the Makefile, not all of them. 
Is that a logically correct aim, or do we need to add all dependencies 
even if only some of the files are newer than Makefile?

Your suggested fix would mean on platforms without "-nt" we would always 
rebuild and that's in fact what I observed (make test rebuilds a lot of 
object files) whereas the "find" variant should work on all platforms 
and only adds the dependencies that are newer than the Makefile. If you 
want to add all dependencies even if only one is newer than the 
Makefile, a "find" based solution would be:

depend:
         @:
         @if [ "X`find $(DEPS) -newer Makefile`" != "X" ]; then \
           ( sed -e '/^# DO NOT DELETE THIS LINE.*/,$$d' < Makefile; \
             echo '# DO NOT DELETE THIS LINE -- make depend depends on 
it.'; \
             echo; \
             for d in $(DEPS); do \
               if [ -f $$d ]; then cat $$d; fi; \
             done ) > Makefile.new; \
           if cmp Makefile.new Makefile >/dev/null 2>&1; then \
             rm -f Makefile.new; \
           else \
             mv -f Makefile.new Makefile; \
           fi; \
         fi
         @:

One final suggestion: if the final solution will still contain a "for d 
in ..." loop, you might want to rename the loop variable from d to 
something else, like e.g. "f". Why? It took me quite some time to 
understand why

sed -e '/^# DO NOT DELETE THIS LINE.*/,$$d' < Makefile;

works although the variable "d" was only defined below that line. Only 
later I noticed, that here the "$$d" has a totally different meaning 
than $$d in the loop (",$$" resolves to ",$" meaning until end of file 
and "d" is the sed delete command). So my confusion was triggered by 
seeing "$$d" in two places close to each other but having totally 
different meaning. If there were no variable "d" IMHO it might become a 
bit more understandable.

BTW: I do like the new build system :)

Regards,

Rainer


-- 
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4444
Please log in as guest with password guest if prompted



More information about the openssl-dev mailing list