Subject: Re: How to properly use shell commands that are defined in make(1)
To: None <tech-pkg@netbsd.org>
From: Roland Illig <rillig@NetBSD.org>
List: tech-pkg
Date: 11/24/2005 18:39:05
This is a multi-part message in MIME format.
--------------050203040502090007000506
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Roland Illig wrote:
> Quite a few shell programs in pkgsrc use commands similar to how they 
> are used in the pkgsrc Makefiles. As it were much better if the tools 
> were used not only similar but _equal_ to inside Makefiles, I've written 
> a quiet little, but useful make(1) target:
> 
> sh-define-cmds:
> .for _c_ in ${CMDS}
>         @${ECHO} ${_c_:Q}"() { "${${_c_}:Q}" \"\$$@\"; }"
> .endfor

Well, this was the naive variant without error checking and the like. 
The Real One is appended.

> It looks cryptic, and indeed it is. But its usage is very simple:
> 
> $ make sh-define-cmds CMDS=MAKE
> MAKE() { /usr/bin/make "$@"; }
> 
> This output can then be evaluated by a shell script using the "." command.

Well, it actually can, but the more usual form is via the "eval" utility.

$ eval "`make sh-define-cmds CMDS=\"MAKE PKG_DELETE PKG_INFO\"`"

$ type MAKE                      MAKE is a function
MAKE ()
{
     /usr/bin/make "$@"
}

$ type PKG_DELETE
PKG_DELETE is a function
PKG_DELETE ()
{
     /home/roland/pkg/sbin/pkg_delete -K /home/roland/pkg/var/db/pkg "$@"
}

Roland

--------------050203040502090007000506
Content-Type: text/plain;
 name="sh-define-cmds.mk"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sh-define-cmds.mk"

.PHONY: sh-define-cmds
sh-define-cmds:
.if defined(CMDS)
.  for _c_ in ${CMDS}
.    if !defined(${_c_})
	@${ECHO} "[sh-define-cmds] error: Undefined variable: ${_c_}." 1>&2
	@${FALSE}
.    else	# This cannot be an .elif because NetBSD 1.6.2's make fails.
.      if empty(${_c_}:M*)
	@${ECHO} "[sh-define-cmds] error: Empty variable: ${_c_}." 1>&2
	@${FALSE}
.      else
	@${ECHO} ${_c_:Q}"() { "${${_c_}:Q}" \"\$$@\"; }"
.      endif
.    endif
.  endfor
.else
	@${ECHO} "usage: "${MAKE:Q}" sh-define-cmds CMDS=COMMAND..." 1>&2
	@${FALSE}
.endif

--------------050203040502090007000506--