I have a problem with GNU Make 4.2.1. It seems there is some interaction between the syntax of static pattern rules and conditional functions that I do not quite understand.
The context: I have a project documented by a set of Markdown files, and I would like to render these files to HTML in order to check them locally. The directory structure should end up looking like this:
some_project/
├── README.md # entry page of documentation
├── doc/ # extra docs
│ ├── foo.md
│ ├── bar.md
│ └── ... # and some more
└── doc_html/ # HTML rendering of the docs
├── Makefile # the Makefile I am trying to write
├── index.html # rendered from README.md
├── foo.html # ............. doc/foo.md
├── bar.html # ............. doc/bar.md
└── ... # etc.
Without the special case of index.html, I could write something like:
%.html: ../doc/%.md
some list of commands $< $@
The problem is that the prerequisite of index.html (namely ../README.md) does not match the pattern. I would like to handle this special case without having to repeat the whole list of commands. This is what I have so far:
DOC_PAGES = $(wildcard ../doc/*.md)
TARGETS = index.html $(patsubst %.md,%.html,$(notdir $(DOC_PAGES)))
# Function to find the source for page $(1)
source = $(if $(findstring index.html,$(1)), \
../README.md, \
$(patsubst %.html,../doc/%.md,$(1)) \
)
all: $(TARGETS)
$(TARGETS): %.html: $(call source,%.html)
@echo some list of commands $< $@
# Check the TARGETS variable and the `source' function
test:
@echo TARGETS = $(TARGETS)
@echo "source(index.html)" = $(call source,index.html)
@echo "source(foo.html)" = $(call source,foo.html)
My source
function seems to work:
$ make test
TARGETS = index.html bar.html foo.html
source(index.html) = ../README.md
source(foo.html) = ../doc/foo.md
However, it doesn't behave properly in the static rule
$ make
make: *** No rule to make target '../doc/index.md', needed by 'index.html'. Stop.
Note that the rule does work if I remove index.html from $(TARGETS)
.
An idea of what I am doing wrong?