Reputation: 2797
I have a Makefile target that depends on a dynamic list of source files. This list is parsed on make
invocations so it could potentially change. It looks like this:
target: $(shell cat foo.txt)
@echo "build target"
foo.txt
changes from time to time. What I'm seeing is that target
will be rebuilt the first time foo.txt
changes content to X
. Say that foo.txt
changes content to Y
then changes back to X
then target
won't be built. I know I can include foo.txt
as a dependency itself but for reasons difficult to explain that's not an option.
As a more concrete example, foo.txt
looks like this:
google.golang.org/[email protected]/dialoptions.go
but could change to something like:
google.golang.org/[email protected]/dialoptions.go
What's going on? Is Makefile caching something?
EDIT
I guess Makefile is caching the timestamp of the dependencies and thus if the dependency files didn't change at all then the target won't be rebuilt? Is there a way to fix this?
Upvotes: 0
Views: 434
Reputation: 100926
Make caches nothing. It has no preserved data whatsoever about any previous build. Make uses the filesystem as its "cache".
Because you're using $(shell cat foo.txt)
, make knows absolutely nothing about the file foo.txt
. All it knows about is the set of files inside the foo.txt
files. It treats all of those as prerequisites.
Then it merely compares the time last modified of the target file (target
) with the time last modified of the prerequisite file that is contained in foo.txt
.
So if foo.txt
contains google.golang.org/[email protected]/dialoptions.go
then it's as if your makefile was written to be:
target: google.golang.org/[email protected]/dialoptions.go
and if the time last modified of target
is older than google.golang.org/[email protected]/dialoptions.go
(use ls -l
to see these values) then make decides target
is out of date and must be rebuilt. If it's newer, then make decides target
is up to date and doesn't have to be rebuilt.
If you change the contents of foo.txt
to be google.golang.org/[email protected]/dialoptions.go
then it compares the time last modified between target
and google.golang.org/[email protected]/dialoptions.go
, the same way.
That's all make does, at its root.
I don't really understand your requirements so I can't give any suggestions for solutions. If you need to have target
rebuilt if either the contents of foo.txt
changes or the modification time on the prerequisite listed in foo.txt
changes, then the only way to do that is list foo.txt
as a prerequisite so make can detect when it was changed. You say you can't do that so... I don't have any good solutions for you.
Upvotes: 3