I've inherited a Linux C app and makefile. In the existing makefile, it had code such as the following:
APPVER=5.01
REL=B
$(APP): $(OBJS) $(MAKEFILE)
echo $APPVER > .sw_ver.txt
echo " " >> .sw_ver.txt
echo $REL >> .sw_ver.txt
$(LD) $(OBJS) $(LDFLAGS) -o $(APP)
At runtime, the app would open this text file and display its version.
In the spirit of Make, rebuilding that .sw_ver.txt
every time file just felt wrong. So I broke it up like the following:
APPVER=5.01
REL=B
$(APP): $(OBJS) $(MAKEFILE) .sw_ver.txt
$(LD) $(OBJS) $(LDFLAGS) -o $(APP)
.sw_ver.txt: $(MAKEFILE)
echo $APPVER > .sw_ver.txt
echo " " >> .sw_ver.txt
echo $REL >> .sw_ver.txt
Steps:
make -B
: it performs the steps, creating the text file and updating the app.- do some update the Makefile
make
: here it says there's no need to update the text file and prunes the rule.
I expected it to see the Makefile has changed, and therefore go update the text file. But it doesn't.
I tried adding a dummy file, but it says seems to get pruned.
What I'm trying to do is if only if the Makefile has changed (thinking that perhaps APPVER
or REL
have changed), then rebuild the .sw_ver.txt
file.
Do you have any advice?
thanks
===== edit #1
hi, so I tried an alternative, to move the version info out to a file instead of trying to create the file during a make run. Since I inherited this stuff, I was trying to change as little as possible.
Just for trivia's sake, it would be interesting to know if there is an answer to the original question.
thanks again
file .sw_ver.txt
5.01 B
Makefile:
$(APP): $(OBJS) $(MAKEFILE) .sw_ver.txt
$(LD) $(OBJS) $(LDFLAGS) -o $(APP)
.sw_ver.txt: $(MAKEFILE)
===== edit #2
I spoke too soon. This setup works if any of the OBJS
are changed, but it does not work if Makefile
itself is changed.
So, kind strangers... any thoughts? Thanks
CodePudding user response:
When I try it out, it seems like $(MAKEFILE)
is an empty variable. Try replacing that with just the literal filename, Makefile
.
By the way, I figured this out by adding echo $(MAKEFILE)
to one of my rules.
CodePudding user response:
Two things to clarify:
MAKEFILE
is not an implicit built-in variable. So if you don't set its value it contains nothing. (You can runmake -p
in a directory without a Makefile to see what variables are there. See https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html)- Based on the reason above, since your
$(MAKEFILE)
is empty, when it expands, the.sw_ver.txt
becomes a rule without prerequisites. Hence if.sw_ver.txt
already exists, nothing will be done to regenerate it. What you get is actually this (note that your syntax$APPVER
and$REL
are actually wrong as well):.sw_ver.txt: # $(MAKEFILE) is empty echo PPVER > .sw_ver.txt # $(A) is empty echo " " >> .sw_ver.txt echo EL >> .sw_ver.txt # $(R) is empty
So what you need to do is:
- Give your
MAKEFILE
variable a value.MAKEFILE := Makefile
- Fix your syntax:
.sw_ver.txt: $(MAKEFILE) echo $(APPVER) > $@ echo " " >> $@ echo $(REL) >> $@
After you do this you should be able to regenerate .sw_ver.txt whenever you update your Makefile.