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: Hongyi Zhao
Subject: Re: Rename positional parameters in customized GNU make functions to enhance readability and maintainability.
Date: Sat, 22 Jan 2022 10:17:58 +0800

On Sat, Jan 22, 2022 at 12:10 AM Kaz Kylheku (gmake)
<729-670-0061@kylheku.com> wrote:
>
> 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.

Got it. Thank you for your detailed explanation.

> 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.

In case there are many packages with very different information from
one another, this method will require so many code lines and still
difficult to maintain compared to currently implemented method in QE
[1-3]. The script [3] mentioned here is the source of the problem
discussed here and what I want to improve.

[1] https://gitlab.com/QEF/q-e/-/blob/develop/install/plugins_list
[2] https://gitlab.com/QEF/q-e/-/blob/develop/install/plugins_makefile
[3] https://gitlab.com/QEF/q-e/-/blob/develop/install/install_utils

Regards,
HZ



reply via email to

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