Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile rule depending on change of number/titles of files instead of change in content of files

Tags:

makefile

I'm using a makefile to automate some document generation. I have several documents in a directory, and one of my makefile rules will generate an index page of those files. The list of files itself is loaded on the fly using list := $(shell ls documents/*.txt) so I don't have to bother manually editing the makefile every time I add, delete, or rename a document. Naturally, I want the index-generation rule to trigger when number/title of files in the documents directory changes, but I don't know how to set up the prerequisites to work in this way.

I could use .PHONY or something similar to force the index-generation to run all the time, but I'd rather not waste the cycles. I tried piping ls to a file list.txt and using that as a prerequisite for my index-generation rule, but that would require either editing list.txt manually (trying to avoid it), or auto-generating it in the makefile (this changes the creation time, so I can't use list.txt in the prerequisite because it would trigger the rule every time).

like image 485
user17925 Avatar asked Jan 20 '26 10:01

user17925


1 Answers

If you need a dependency on the number of files, then... why not just depend on the number itself? The number will be represented as a dummy file that is created when the specified nubmer of files is in the documents directory.

NUMBER=$(shell ls documents/*.txt | wc -l).files
# This yields name like 2.files, 3.files, etc...
# .PHONY $(NUMBER) -- NOT a phony target!

$(NUMBER):
        rm *.files    # Remove previous trigger
        touch $(NUMBER)

index.txt: $(NUMBER)
        ...generate index.txt...

While number of files is one property to track, instead you may depend on a hash of a directory listing. It's very unlikely that hash function will be the same for two listings that occur in your workflow. Here's an example:

NUMBER=$(shell ls -l documents/*.txt | md5sum | sed 's/[[:space:]].*//').files

Note using -l -- this way you'll depend on full listing of files, which includes modification time, sizes and file names. Bu if you don't need it, you may drop the option.

Note: sed was needed because on my system md5sum yields some stuff after the hash-sum itself.

like image 74
P Shved Avatar answered Jan 23 '26 09:01

P Shved