ealeon
ealeon

Reputation: 12452

Makefile functions

New to Makefiles

Is there a way to define a function in Makefile for de-duping code. For example I have a Makefile

.PHONE do-something-one-dependent
do-something-one-dependent:
    <some logic>

.PHONE do-something-two-dependent
do-something-two-dependent:
    <some different logic>

.PHONY: do-something-one
do-something-one: do-something-one-dependent
ifeq ($(COPY), )
        echo "Not copying"
else
        echo "Copying to: $(COPY)"
        mv $(WORKDIR) $(COPY)
endif

PHONY: do-something-two
do-something-one: do-something-two-dependent
ifeq ($(COPY), )
        echo "Not copying"
else
        echo "Copying to: $(COPY)"
        mv $(WORKDIR) $(COPY)
endif

as you can tell do-something-one and do-something-two do the same thing except that they are dependent upon different make targets that do different things

I was wondering if the logic for do-something-one and do-something-two to be farmed out to a function

Upvotes: 0

Views: 228

Answers (1)

MadScientist
MadScientist

Reputation: 100816

You don't have to declare all the dependencies at the same time you create the recipe. They can be added later. Further, you can put more than one target in the same recipe declaration. And you can make variables. So, you can do something like this:

TARGETS := do-something-one do-something-two

.PHONY: $(TARGETS)
$(TARGETS):
ifeq ($(COPY),)
        echo Not copying
else
        echo "Copying to: $(COPY)"
        mv $(WORKDIR) $(COPY)
endif

do-something-one: do-something-one-dependent
do-something-two: do-something-two-dependent

There are various other more sophisticated ways but often they make the code more gross rather than less.

ETA

For different variables you can either use target-specific variables:

TARGETS := do-something-one do-something-two

.PHONY: $(TARGETS)
$(TARGETS):
ifeq ($(COPY),)
        echo Not copying
else
        echo "Copying to: $(COPY)"
        mv $(FROMDIR) $(COPY)
endif

do-something-one: do-something-one-dependent
do-something-one: FROMDIR = $(WORKDIR)
do-something-two: do-something-two-dependent
do-something-two: FROMDIR = $(TEMPDIR)

Or, you can switch to full-fledged functions. That would look something like this:

TARGETS := do-something-one do-something-two

define MAKE_A_TARGET
.PHONY: $1
$1: $3
ifeq ($$(COPY),)
        echo Not copying
else
        echo "Copying to: $$(COPY)"
        mv $2 $$(COPY)
endif
endef

$(eval $(call MAKE_A_TARGET,do-something-one,$(WORKDIR),do-something-one-dependent))
$(eval $(call MAKE_A_TARGET,do-something-two,$(TEMPDIR),do-something-two-dependent))

Upvotes: 1

Related Questions