ceving
ceving

Reputation: 23861

How to ignore a rule if its dependency does not exist?

I have a Makefile with two rules. One which converts a database file into a SQL file and one which does the opposite.

all:

data.sql: data.sqlite3
    sqlite3 $< .dump > $@

data.sqlite3: data.sql
    sqlite3 $@ < $<

This works, but I get warnings about circular dependencies.

$ rm data.sql
$ make data.sql
make: Circular data.sqlite3 <- data.sql dependency dropped.
sqlite3 data.sqlite3 .dump > data.sql

$ rm data.sqlite3 
$ make data.sqlite3
make: Circular data.sql <- data.sqlite3 dependency dropped.
sqlite3 data.sqlite3 < data.sql

Is it possible to get rid of the warning?

Upvotes: 1

Views: 96

Answers (2)

Mike Kinghan
Mike Kinghan

Reputation: 61610

From your own solution I gather it's never the case that an .sql and an .sqlite3 exist at the same time. In that case you can be more concise by making each missing .sql or .sqlite3 as a side-effect of pretending to make a proxy target but never actually doing it. Here's an illustration:

# These are the missing `.sql` files for which a `.sqlite3` exists...
sql_missing = $(filter-out \
    $(wildcard *.sql),$(addsuffix .sql,$(basename $(wildcard *.sqlite3))))
# These are the missing `.sqlite3` files for which an `.sql` exists...
sqlite3_missing = $(filter-out \
    $(wildcard *sqlite3),$(addsuffix .sqlite3,$(basename $(wildcard *.sql))))
# There are the proxy targets...
targs = $(addsuffix _missing,$(sql_missing) $(sqlite3_missing))

.PHONY: all

all: $(targs)

%.sql_missing: %.sqlite3
    @echo "$< => $(basename $@).sql"
    @touch $(basename $@).sql

%.sqlite3_missing: %.sql
    @echo "$< => $(basename $@).sqlite3"
    @touch $(basename $@).sqlite3

This caters for a population of either filetype or both in the directory, as long as you only want to remake the missing file of each incomplete pair.

In use:

$ ls
Makefile
$ touch f1.sql
$ touch f2.sqlite3
$ make
f2.sqlite3 => f2.sql
f1.sql => f1.sqlite3
$ ls
f1.sql  f1.sqlite3  f2.sql  f2.sqlite3  Makefile
$ make
make: Nothing to be done for 'all'.

Upvotes: 1

ceving
ceving

Reputation: 23861

I think I got it. A bit verbose but it seems to work.

DBFILE := data.sqlite3
SQLFILE := data.sql

ifeq ("$(wildcard $(SQLFILE))","")
MISSING := $(SQLFILE)
endif

ifeq ("$(wildcard $(DBFILE))","")
MISSING := $(DBFILE)
endif

all: $(MISSING)

ifeq ("$(wildcard $(SQLFILE))","")
$(SQLFILE): $(DBFILE)
    sqlite3 $< .dump > $@
endif

ifeq ("$(wildcard $(DBFILE))","")
$(DBFILE): $(SQLFILE)
    sqlite3 $@ < $<
endif

Upvotes: 0

Related Questions