[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