help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Can the exit status of the code block in @(...) be obtained from out


From: Paul Smith
Subject: Re: Can the exit status of the code block in @(...) be obtained from outside the @() structure?
Date: Fri, 21 Jan 2022 14:05:40 -0500
User-agent: Evolution 3.36.5-0ubuntu1

On Fri, 2022-01-21 at 09:24 +0800, Hongyi Zhao wrote:
> define download_and_unpack 
>   @package = $(1)
>   @package_URL = $(2)
>   @package_directory = $(3)
>   @package_code = $(4)
>   @package_archive = ../archive/`echo "$(package)" | sed 's/.*\///;s/.*=//'`
> 
>   @(
>   if ! gzip -t $(package_archive) > /dev/null 2>&1 ; then \

As I've already mentioned, we cannot help if you only show us the
DEFINITION of the variable but don't show us how the variable is
REFERENCED.

However, in this case we can already say that this cannot work.  You
are forgetting a fundamental concept of makefiles.

A rule in a makefile has the form:

  <target>: <prerequisites>
          <recipe>

(where <prerequisites> can be empty).

The content inside the <recipe> MUST BE a shell script.  It is not
makefile syntax, it is SHELL syntax.  You cannot put makefile
operations, like setting make variables, in the recipe.  Only shell
operations, like setting shell variables, can be in the recipe.

It doesn't matter how complicated the content of <recipe> is, how many
variables it contains, functions it uses, etc.: once it's expanded
everything in it must be shell syntax and not makefile syntax.

So when you put a reference to the variable $(download_and_unpack) in a
recipe, like this:

  <target>: <prerequisites>
          $(download_and_unpack)

the variable reference is in a recipe, so the entirety of the expanded
value of that variable will be given to the shell to be interpreted.

This:

  package = ...

is not valid shell syntax.  Make variables can be assigned like this,
but we know this is in a recipe so it can't use make syntax, it must
use shell syntax, and shell variables cannot have whitespace around the
"=" sign.  Try it: at your shell prompt type:

  $ package = foo

and you'll get the error "package: Command not found" just as you see.

If you wanted to set a SHELL variable you have to use SHELL syntax:

  @package=$(1)
  @package_URL=$(2)
  @package_directory=$(3)
  @package_code=$(4)
  @package_archive=../archive/`echo "$(package)" | sed 's/.*\///;s/.*=//'`

However, this won't work for the reasons we explained before: every
separate line in a recipe is run in a separate shell.  So these SHELL
variables are assigned, then the shell exits and the values are lost,
then a new shell is started.

As mentioned before, the entire script must be contained in a single
logical line if you want the same shell to interpret it all.  So you'll
have to add "\" to combine all these into a single logical line:

  define download_and_unpack
    package='$(1)' ; \
    package_URL='$(2)' ; \
    package_directory='$(3)' ; \
    package_code='$(4)' ; \
    package_archive=../archive/`echo "$(package)" | sed 's/.*\///;s/.*=//'` ; \
    ( \
    if ! gzip -t $(package_archive) > /dev/null 2>&1 ; then \

etc.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]