RTY
RTY

Reputation: 5

In makefile how to compare time stamps of the same file before and after changing it by shell command?

First,this makefile dose not work

all:
    A=$(shell stat -c %Y test1);\
    echo "A is $$A";\
    touch test1;\
    B=$(shell stat -c %Y test1);\
    echo "B is $$B";\
    if (($$A<$$B)); then echo true; fi

output in shell:

$ make
A=1513082575;\
echo "A is $A";\
touch test1;\
B=1513082575;\
echo "B is $B";\
if (($A<$B)); then echo true; fi
A is 1513082575
B is 1513082575

the time is not changed, I think touch test1 is just executed after A=$(shell stat -c %Y test1); and B=$(shell stat -c %Y test1);

and this one seems works:

all:
    A=$(shell stat -c %Y test1);\
    echo "A is $$A";\
    C=$(shell touch test1);\
    B=$(shell stat -c %Y test1);\
    echo "B is $$B";\
    if (($$A<$$B)); then echo true; fi

output in shell:

$ make
A=1513083955;\
echo "A is $A";\
C=;\
B=1513084224;\
echo "B is $B";\
if (($A<$B)); then echo true; fi
A is 1513083955
B is 1513084224
true

but $(shell touch test1) is not I want, is there any other way to implement this feature?

Upvotes: 0

Views: 898

Answers (2)

Renaud Pacalet
Renaud Pacalet

Reputation: 29050

The $(shell...) in your recipe are expanded by make before the recipe is actually passed to the shell. So, if a file named test1 exists and its timestamp is 1513082575, make first expands your recipe as:

A=1513082575;\
echo "A is $A";\
touch test1;\
B=1513082575;\
echo "B is $B";\
if (($A<$B)); then echo true; fi

which, when executed by the shell gives the result you got. If you really want the timestamps to be taken by your recipe, do not use $(shell...):

all:
    A=$$(stat -c %Y test1);\
    echo "A is $$A";\
    touch test1;\
    B=$$(stat -c %Y test1);\
    echo "B is $$B";\
    if ((A<B)); then echo true; fi

Note 1: escape the expansion by make of the $ you want to preserve for the shell by doubling them ($$).

Note 2: from the arithmetic evaluation section of the bash manual:

Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax.

So, in bash, if((A<B))... does the same as if(($A<$B))... and is preferable because:

  • escaping the $ in the recipe is not needed,
  • you do not need to pay attention to exotic values of your shell variables (blanks, quoting...).

Upvotes: 1

RTY
RTY

Reputation: 5

SriniV,it works just add some $ in your answer and then place it in makefile,Thank you!

 all:
    A=$$(stat -c %Y test1);\
    echo "A is $$A";\
   touch test1;\
   B=$$(stat -c %Y test1);\
   echo "B is $$B";\
   if (($$A<$$B)); then echo true; fi

Upvotes: 0

Related Questions