Chaining dynamic prereqs in Makefile

275 views Asked by At

I'm trying to figure out a Makefile problem I've got. I start with a lot of files in a telemetry/ directory, and for each one I need to create a corresponding file in a features/ directory.

The list of filenames in the telemetry/ directory is cached in a filelist file, and I define an allfeats target to encompass all the file-level targets. Except the allfeats target doesn't actually work.

My Makefile (heavily trimmed to just show this issue) looks like this:

MYSAMP:=$(shell cat filelist)

allfeats: $(patsubst %,features/%-feat.rds,$(MYSAMP))
        @echo done

features/%-feat.rds: telemetry/%
        Rscript -e 'saveRDS(process("$<"), "$@")'

print-%:
        @echo $* = $($*)

But something about the timing of variable propagation, I think, isn't letting me chain rules the way I intend:

% make -n allfeats
make: *** No rule to make target `features/709731-feat.rds', needed by `allfeats'.  Stop.

It does actually know how to create that target if I specify it explicitly:

% make -n features/709731-feat.rds
Rscript -e 'saveRDS(process("telemetry/709731"), "features/709731-feat.rds")'

Is there a different way to define my rules (or variables) that will work as intended?

1

There are 1 answers

0
Ken Williams On

I figured out the problem. I had generated the filelist file by doing this:

% ls telemetry > filelist

But I forgot that my ls is aliased like so:

% which ls
ls='ls -FG --color --hide="NTUSER.DAT*"'

So I had the coloration escape sequences in the file too, which were invisible to the naked eye, but reveal themselves in an octal dump:

% head filelist | od -a
0000000 esc   [   0   m esc   [   0   m   7   0   9   7   3   1 esc   [
0000020   0   m  nl esc   [   0   m   8   0   0   3   3   3 esc   [   0
0000040   m  nl esc   [   0   m   8   0   0   3   3   4 esc   [   0   m
0000060  nl esc   [   0   m   8   0   0   3   3   5 esc   [   0   m  nl
0000100 esc   [   0   m   8   0   0   8   3   2 esc   [   0   m  nl esc
0000120   [   0   m   8   0   0   8   3   3 esc   [   0   m  nl esc   [
0000140   0   m   8   0   0   8   3   4 esc   [   0   m  nl esc   [   0
0000160   m   8   0   0   8   3   6 esc   [   0   m  nl esc   [   0   m
0000200   8   0   0   8   4   8 esc   [   0   m  nl esc   [   0   m   8
0000220   0   2   0   3   1 esc   [   0   m  nl

Once I cleaned those out, the Makefile chaining works as expected.