bug-make
[Top][All Lists]
Advanced

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

Fwd: Re: Target-specific variable in subdirectory problem


From: Sven C. Dack
Subject: Fwd: Re: Target-specific variable in subdirectory problem
Date: Thu, 3 Aug 2017 16:46:50 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1

Hello Benjamin,

it's a common practise to create a Makefile for each subdirectory and
have it include definitions from a parent Makefile. That's probably why
you don't see that many directory-spanning features in make. It's easier
to manage Makefiles in a structure similar to the source code instead of
having it all packed into one Makefile, especially the larger your
project grows.

Here is an example of what you can. Assume you have a top-level
directory with three subdirectories and separate Makefiles in them:

Makefile  Makefile.subs  sub-a/Makefile  sub-sub/Makefile sub-z/Makefile

--- Makefile ---
SUBS := $(wildcard sub-*/)
SUB_TARGETS := $(patsubst %,%%,$(SUBS))

$(SUB_TARGETS):
    make -C $(dir $@) $(notdir $@)

FOO := "Makefiles"
include Makefile.subs

--- Makefile.subs ---
test-%:
    @echo "$(FOO)"

--- sub-a/Makefile ---
FOO := "Hello"
include ../Makefile.subs

--- sub-sub/Makefile ---
FOO := "of"
include ../Makefile.subs

--- sub-z/Makefile ---
FOO := "World"
include ../Makefile.subs

When you now enter "make sub-a/test-1 sub-z/test-2 sub-sub/test-3
test-4" will you get:

make -C sub-a/ test-1
make[1]: Entering directory '/home/sven/x/sub-a'
Hello
make[1]: Leaving directory '/home/sven/x/sub-a'
make -C sub-z/ test-2
make[1]: Entering directory '/home/sven/x/sub-z'
World
make[1]: Leaving directory '/home/sven/x/sub-z'
make -C sub-sub/ test-3
make[1]: Entering directory '/home/sven/x/sub-sub'
of
make[1]: Leaving directory '/home/sven/x/sub-sub'
Makefiles


The Makefiles of the subdirectories are simple and straight-forward.
These define FOO and only include a parent Makefile called
Makefile.subs, which defines your "test-%" rule to print the value of FOO.

The top-level Makefile uses the 'wildcard' and 'patsubst' functions of
make to create a list of targets "sub-a/% sub-z/% sub-sub/%" and uses it
for a rule, which will call a second make to run it in a subdirectory.

Note the the top-level Makefile also defines FOO and includes
Makefile.subs and hence prints out "Makefiles" for the last target "test-4".

Cheers




On 03/08/17 13:59, Benjamin Cama wrote:
...
Concerning my real use case, it is just to define target-specific
variables for some recipes which are located in subdirectories. I am not
looking for the target-specific variable feature in filenames strictly
matching the target in the current directory. I looked strange that no
variable was defined when in a subdirectory.

Anyway, it seems that a global variable would solve my problem, and
indeed it looks a bit more right this way: I can still get the stem in
my recipe (with $*), and everything works as expected. It's just that
the global namespace is “polluted” by this variable which is used only
in my particular recipe. And this is where I may be mistaken on the use
of target-specific variable: I tend to use them as a kind of “private
namespace” feature, when I define something that will be used only in
one particular recipe. But then there is no difference with global
variable in this case, apart from namespace pollution. I now understand
that this feature is better suited to overriding a global variable in
some specific recipe: is this right?

To further enhance my understanding of the “right” usage of Makefiles,
would you advise me to explicitly specify the subdirectory in the target
definition? Because I feel that counting on pattern rules to match in
subdirectory is kind of hackish, now. Like:

         $(SUBDIR)/target-%:
           …

And in my particular case, I actually know the $(SUBDIR), but would it
be right then to call make with:

         make SUBDIR=foo foo/target-1234

? It looks redundant to me.

Thanks,




reply via email to

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