Maryan
Maryan

Reputation: 1574

idiomatic Makefile and command arguments

Context

I have a Makefile to run docker-ized service

RUN = docker-compose run $(ARGS) --rm serivce

.PHONY: shell
shell:
    ${RUN} /bin/sh

.PHONY: server
server:
    $(eval ARGS=--service-ports) ${RUN}

Problem

server task needs additional arguments(--service-ports) set to start the container. Just hardcoding the arguments into the RUN wont work because shell would publish port as well and will fail(having the server running).

Question

What's the idiomatic way to specify arguments ARGS depending on the context?

$(eval ARGS=--service-ports) works but is there a "right way"?

Upvotes: 2

Views: 709

Answers (2)

mkasberg
mkasberg

Reputation: 17322

I think you could simply split your variables up into more parts:

COMMAND = docker-compose run --rm $(ARGS)
CONTAINER = service

.PHONY: shell
shell:
    ${COMMAND} ${CONTAINER} /bin/sh

.PHONY: server
server:
    ${COMMAND} --service-ports ${CONTAINER}

Upvotes: 0

MadScientist
MadScientist

Reputation: 100916

The eval is definitely not right. What if someone runs make server shell? Now the shell will have that argument set, because the eval resets it globally.

Is there some reason you can't just write:

server:
         $(RUN) --service-ports

? In general if you need a variable customized on a per-target basis you have two options:

You can use target-specific variables:

server: ARGS = --service-ports
server:
         $(RUN)

Or you can use recursively-expanded variables:

server_ARGS = --service-ports

RUN = docker-compose run $($@_ARGS) --rm service

server:
         $(RUN)

Upvotes: 3

Related Questions