1

I'm completely stumped on how to do this in a Makefile

Let's say I have a target. Inside the target I have a loop. How do i change a variable to keep track of the iterations?

For example:

COUNTER = 0
target:
    (loop){
        COUNTER++
        echo COUNTER
}

I know that variables in Makefiles are only expanded, and I'm not sure if they can be permanently changed, but there has to be a way to do this, right? :(

Here are some sources that are asking similar questions. It seems like those examples only change the variable temporarily:

Maybe I have to use the eval function somehow?

Maybe I have to append onto a Makefile string a character each time and then use something in the shell to count the characters?

Community
  • 1
  • 1
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • The first answer in your first example gives a working solution. Why are you still asking the question? Also, your use of "temporarily" and "permanently" makes no sense. – Beta Aug 24 '11 at 11:28
  • not for iteration. I would have to make a new variable to hold every number – Trevor Hickey Aug 24 '11 at 19:59
  • So... you want to increment a variable inside a rule, then use the new value in another rule? Do you know the order of operation? Do the two rules have any particular relationship? – Beta Aug 24 '11 at 21:10
  • basically i have .PHONY target called clean. all I want to do is count how many files are actually deleted. The target loops through each file and if it's there, it deletes it. So right after the "delete file" command i would want to increment... because if the file is not there, these two commands would be skipped – Trevor Hickey Aug 24 '11 at 23:22

3 Answers3

5

If the variable doesn't have to survive the rule, this should do (I'm assuming bash):

clean:
    @n=0 ; \
   for x in $(THINGS_TO_BE_DELETED); do \
     if [ -f $$x ] ; then \
       rm $$x; \
       let "n+=1" ; \
     fi ; \
   done ; \
   echo deleted $$n files;
Beta
  • 96,650
  • 16
  • 149
  • 150
  • ahhhh! i'm so close! ERROR: /bin/sh: let: not found 'let' is a bash builtin – Trevor Hickey Aug 25 '11 at 01:26
  • @Trevor Hickey: all right, what shell do you use? (If you're not sure, try `echo $SHELL` from the command line, or better yet in a command in a rule.) – Beta Aug 25 '11 at 02:27
  • GOT IT! if you don't set the variable 'SHELL', Make uses /bin/sh by default. so by adding "SHELL:= /bin/bash", i could use the 'let' command. I never expected to get such great help, thanks for your patience Beta – Trevor Hickey Aug 25 '11 at 03:01
2

This is similar to the accepted answer, but the syntax below should work with a POSIX compliant shell. Quotes should also be used inside of the test.

clean:
    @n=0; \
    for x in *.a *.b *.c ; do \
      if [ -f "$$x" ]; then \
        rm "$$x"; \
        n=$$((n+1)); \
      fi; \
    done; \
    echo deleted $$n files;

Note: tabs must be used for indentation

Renec1943
  • 21
  • 1
  • Welcome. Thank you for reading the previous answers, acknowledging the similarity, and highlighting what makes your answer different. Those are all habits we encourage when answering old questions on Stack Overflow. – Jeremy Caney Oct 06 '21 at 17:25
2

Here is one solution: Write a simple script like this:

#!/bin/bash
count=`cat count.txt`
count=$((count + 1))
echo $count
cat $count > count.txt

Initialize the file by doing

$ echo "0" > count.txt

Then include it as a .PHONY requirement to build whatever you'd like.

Robert Martin
  • 16,759
  • 15
  • 61
  • 87