.if and Makefile issues

Don Lewis truckman at FreeBSD.org
Mon Mar 26 05:22:41 UTC 2018


On 25 Mar, Gary Aitken wrote:
> Bewildered and frustrated, looking for some guidance on a seemingly
> simple task: check the existence of a file and rename it.
> 
> Looking at a number of examples in the Porter's guide, I should be
> able to do something like this:
> 
> post-build:
> <ht>echo "***** post-build *****"
> #<ht>Avoid executable name conflict with dcraw port
> <ht>.if exists ${WRKSRC}/dcraw
> <ht>echo ===== dcraw exists =====
> <ht>mv ${WRKSRC}/dcraw ${WRKSRC}/${PORTNAME}-dcraw
> <ht>.else
> <ht>echo ===== dcraw does not exist =====
> <ht>.endif
> 
> That causes:
> echo "***** post-build *****"
> ***** post-build *****
> .if exists /usr/ports/graphics/ufraw-devel/work/ufraw-6d3259a/dcraw
> make[1]: exec(.if) failed (No such file or directory)
> *** Error code 1

Since the .if is indented, it is being treated as a shell command,
and .if isn't being found in $PATH.

> I then tried adding parens:
> 
> post-build:
> <ht>echo "***** post-build *****"
> #<ht>Avoid executable name conflict with dcraw port
> <ht>.if exists(${WRKSRC}/dcraw)
> <ht>echo "===== dcraw exists ====="
> <ht>mv ${WRKSRC}/dcraw ${WRKSRC}/${PORTNAME}-dcraw
> <ht>.else
> <ht>echo "===== dcraw does not exist ====="
> <ht>.endif
> 
> echo "***** post-build *****"
> ***** post-build *****
> .if exists(/usr/ports/graphics/ufraw-devel/work/ufraw-6d3259a/dcraw)
> Syntax error: "(" unexpected
> *** Error code 2

Ditto, but the shell command has a shell syntax error.
 
> I finally got this to do *something*:
> 
> post-build:
> <ht>echo "***** post-build *****"
> #   Avoid executable name conflict with dcraw port
> .if exists ${WRKSRC}/dcraw
> echo ===== dcraw exists =====
> mv ${WRKSRC}/dcraw ${WRKSRC}/${PORTNAME}-dcraw
> .else
> <ht>echo ===== dcraw does not exist =====
> .endif
> 
> echo "***** post-build *****"
> ***** post-build *****
> echo "===== dcraw does not exist ====="
> ===== dcraw does not exist =====
> 
> Unfortunately, the file *does* exist.

The .if is treated as a make directive in this case, but it is
evaluated at the time that make is first invoked, probably when
when "make build" is first executed, or earlier.

> Can someone enlighten me as to what is going on in the above three
> situations, to further my education?
> Any hints / pointers would be much appreciated:
> 
> 1. Why does the .if, .else, and .endif have to have no leading whitespace?

If there is leading whitespace, then make assumes they are shell
commands.

> 2. Why does it require the <ht> on the stmt after the else but not
>     after the .if?  (Same behavior with tabs on the ones after .if)

Probably because the .if evaluates false, so anything between the .if
and the .else isn't even parsed.

> 3. Why doesn't it find the file?

Because the file doesn't exist when the make first parses the Makefile.

> 4. What's a right way to do this?

Use a shell runtime test:

post-build:
<ht>echo "***** post-build *****"
<ht>#   Avoid executable name conflict with dcraw port
<ht>if [ -e ${WRKSRC}/dcraw ]; then
<ht><ht>echo ===== dcraw exists =====
<ht><ht>mv ${WRKSRC}/dcraw ${WRKSRC}/${PORTNAME}-dcraw
<ht>else
<ht><ht>echo ===== dcraw does not exist =====
<ht>fi


More information about the freebsd-ports mailing list