help-make
[Top][All Lists]
Advanced

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

Re: Rename positional parameters in customized GNU make functions to enh


From: Kaz Kylheku (gmake)
Subject: Re: Rename positional parameters in customized GNU make functions to enhance readability and maintainability.
Date: Fri, 21 Jan 2022 08:10:12 -0800
User-agent: Roundcube Webmail/0.9.2

On 2022-01-21 02:34, Hongyi Zhao wrote:
I try to redefine the download_and_unpack function used here [1] as follows:

```
define download_and_unpack
  @package := $(1)
    ^

What is that? Is this supposed to be the echo suppressing character used in recipe lines?

You seem to have a misconception about how make works.

You cannot assign variables in makefile recipes; they are shell scripts.

Variable assignments are processed when a Makefile is parsed by make, before
recipes execute. During execution of recipes, target-specific variables
are set at run-time and expanded in the recipe and of course special ones
like $@ and $<.

No assignment syntax is available in a recipe line.

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

You could do this with shell variables. But since recipe lines
are run in separate shell invocations, shell variables set in one
line cannot be seen in another (unless you globally override that
with .ONESHELL:, which I wouldn't recommend in an existing, complex
Makefile that you're trying to customize).

You can do it like this:

define big_recipe_macro
  arg1=$(1) \
  arg2=$(2) \
  ... = ... \
  ( command1 $$arg1 $$arg2 && \
    command1 --foo $$arg2 $$arg3 && \
    ...  )
endef

Don't forget that double $$ are needed in a macro to pass a single $
to the macro expansion.

Now, here is a topic on a tangent, which may be relevant.

In Makefiles which work with tuples of variables which are related,
you can use named variables to simulate a data structure.

If I were developing a Makefile in which there is a "package" concept
which has properties like "directory", "URL", and so on, here is
what I would do:

Have a place where the database is declared. This could be scattered in
multiple include makefiles:

   # define package foo
   foo.name := "foo"
   foo.version := 1.2
   foo.url := "https://foo.org/downloads/foo-$(foo.version).tar.gz"
   foo.directory := "packages/$(foo.name)"

   # define package bar
   bar.name := "foo"
   bar.version := 4.7.1
   bar.url := "https://bar.com/packages/bar-$(bar.version).tar.xz"
   bar.directory := "packages/$(bar.name)"

How named variables work is that we can have the package name in
a variable, e.g.:

   package=foo

so now to access $(foo.version), we can do this:

   $($(package).version)

Make will expand $(package) to foo, so this becomes $(foo.version)
and that then expands to 1.2.

Now you can use a single parameter in a recipe macro, so that
$(1) gives the package name:

   define download_and_unpack
     cd $((1).directory) && wget $($(1).url) -o $($(1).directory)
     ...
   endef

Still pretty ugly, but at least the property system is more or less
clearly organized.



reply via email to

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