Makefile dynamic variables as prerequisites - makefile

Perhaps it's something that I'm getting wrong. Basically my task is to use make to automate a build, deploy, starting, stopping of different services.
One of the things that I'm trying to do is to have a variable as a target prerequisite, however that variable has to be changed in another target.
Here's a basic sample of what I'm trying to do:
IMAGE_COUNT=-1
count_images:
$(eval IMAGE_COUNT=5)
_should_build: $(if $(findstring $(IMAGE_COUNT),0), build,)
build:
...some procedure to build...
start: _should_build
...some procedure to start a service...
Obviously the $(IMAGE_COUNT) in _should_build check will stay as -1, but what I want is to have the $(IMAGE_COUNT) become a 5 during the prerequisite check. A thing to note is that I cannot place the counting of images outside the count_images target.
Does anyone know if this is possible at all?

Perhaps it's something that I'm getting wrong.
That "something" is called an evaluation order.
One of the things that I'm trying to do is to have a variable as a target prerequisite, however that variable has to be changed in another target.
Not a target, but a recipe. The recipes are preprocessed before execution. While the prerequisites are preprocessed on the first pass. In fact, changing the value of a make's variable inside a recipe in 90% of cases is a mistake. (Also remember that all preprocessing is done before feeding the recipe to the shell).
Does anyone know if this is possible at all?
Everything is possible, of course, but not this way.
A thing to note is that I cannot place the counting of images outside the count_images target.
Most probably, you can.
Anyway, the point is that some shell script (a recipe, or a part of a recipe) should return a number. However, such return values cannot be stored in a make's variable. Re-think your design and find another way for communication between your targets.

Related

How to detect Makefile re-evaluation due to include

I have a Makefile (GNU make) which will re-evaluate itself under certain circumstances due to an include. I would like to be able to determine, during evaluation and before rule execution, whether this is the first "pass" or the second "pass" (the re-evaluation). Is there a way to do this?
I have tried exporting a variable, but this does not seem to work (it seems the re-evaluation is not treated as a sub-make, which I guess makes sense).
I am working on reformulating the Makefile to remove the re-evaluation but it's not simple for my application and I was hoping for a short-term fix...
Are you talking about the fact that make restart itself if any included files (with include) has been remade during the first attempt ? If so, you're looking for the MAKE_RESTARTS special variable, which (quoting the manual) will contain the number of times this instance has restarted

Makefile - does using .PHONY for running commands was intended when creating make?

I know we can set up commands such as all, clean, install etc in makefile and use .PHONY to tell make they're not associated with files.
But I was wondering - when creating make and makefile - was this kind of use (to run such commands) combined with .PHONY designed for that purpose? Or maybe .PHONY was added later to easily extend make to support those kind of commands?
I also read this but there wasn't anything else there except the regular known usage.
Thanks!
I do not know the history of GNU make.
The use of .PHONY is exactly what you suspect: have targets (which can thus be goals, or commands, if you wish) that are not files, and that work even if, by accident, a file with the same name exists. It is one single and clearly defined purpose.
In certain cases you want to force a target file to be re-built even if it is up-to-date, and you can declare it a prerequisite of .PHONY for this purpose, but it is frequently the sign that your makefile is not what it should be.
Another frequent situation is the grouping of several targets (real or phony) as prerequisites of one single other phony target.
But in both cases, we can say that the resulting phony target is a kind of command. In the first case it is a command that forces the build of a file. In the second it is a kind of alias for a series of actions.

GNU make empty recipe vs. no recipe

Looking at the GNU make manual, what exactly is the difference between an empty recipe and no recipe (for example see one instance in Rules without Recipes or Prerequisites)? More importantly, when should one use/avoid each of these two recipes?
In my current understanding, one should always use
target: ;
because sometimes an implicit rule could defeat one's purpose of no rule.
A given target can have only one recipe. If you declare an empty recipe then you've now given that target that recipe and it won't be searched for via implicit rules. Also if you try to give that same target another recipe, then make will complain.
"No recipe" just means you're adding more prerequisites to an existing target or, if you don't list prerequisites, you're just informing make that this is a target you're interested in. But you're not overriding any recipe lookup that make will do elsewhere.
It's definitely not true that one should always use one or the other: the one you use depends on what you're trying to achieve.
I don't know what you mean when you say defeat one's purpose of no rule so I can't respond to that... what are you trying to achieve when you say "no rule"?

Using Makefile variable before definition in included file

I've encountered a little problem during my Makefile learning adventure.
I have prepared two scripts. The first one is the main Makefile:
all:
#echo $(COMPONENTNAME)
include ~/Projects/tests/mk
And here's the mk file
COMPONENTNAME:=ISeeYou
Now, when I run
make all
I get
ISeeYou
I am not sure why... I was convinced that a variable must be defined before it is used. And the include is after COMPONENTNAME is being used. My suspicion is that all of the includes are done first, and then the target creation is started. Is that the case?
My suspicion is that all of the includes are done first, and then the target creation is started.
Yes, you are right.
All global sections in Makefile should be completely parsed before make is able to decide, which targets(and in which order) should be built. Target's recipes are evaluated only when it is needed to build target. This is explicitely stated in make manual:
The other way in which make processes recipes is by expanding any variable references in them. This occurs after make has finished reading all the makefiles and the target is determined to be out of date; so, the recipes for targets which are not rebuilt are never expanded.

Multiple instances of the same target for make

I am working on a Makefile written by someone else in my lab and I see the following:
include /path/to/Makefile.inc
TARGET_A: pre_req_1 pre_req_2
cmd_1;
cmd_2;
...
When I look at /path/to/Makefile.inc I see that it also includes a target TARGET_A
with other pre-requisites and recipes.
Is this a normal practice? (and would it work?) Would make treat the two rules separately? Can we safely make any assumptions about which one is considered first?
It is a dangerous practice since it is confusing to know which one is applied.
The "include" will act has if the included file content was in the Makefile, and the targets will be overrided while reading the Makefile. So, the last target will be honored, and the first one (in the included file) will be ignored.

Resources