Subject: Re: How to properly use shell commands that are defined in make(1)
To: None <>
From: Roland Illig <>
List: tech-pkg
Date: 11/24/2005 18:39:05
This is a multi-part message in MIME format.
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
     /usr/bin/make "$@"

PKG_DELETE is a function
     /home/roland/pkg/sbin/pkg_delete -K /home/roland/pkg/var/db/pkg "$@"


Content-Type: text/plain;
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;

.PHONY: sh-define-cmds
.if defined(CMDS)
.  for _c_ in ${CMDS}
.    if !defined(${_c_})
	@${ECHO} "[sh-define-cmds] error: Undefined variable: ${_c_}." 1>&2
.    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
.      else
	@${ECHO} ${_c_:Q}"() { "${${_c_}:Q}" \"\$$@\"; }"
.      endif
.    endif
.  endfor
	@${ECHO} "usage: "${MAKE:Q}" sh-define-cmds CMDS=COMMAND..." 1>&2