0

so I need to add some logic to an existing makefile. here's the rule I'm working on:

deploy:
ifneq ($(filter $(SERVICE),$(AVAILABLE_SERVICES)),)
    SA=$(SERVICE)
else
    SA="default"
endif
    export SA
    # do something ...
    # do something else

I essentially need to export SA variable based on a condition, but this wouldn't work fine since I think SA after condition does not related to the SA inside the condition

Any suggestion on how to set the variable inside if statement and then use it afterwards? (within the rule)

2
  • 2
    You are mixing makefile code with bash code. It can't work. They have nothing to do with each other. Commented Jul 25, 2019 at 16:56
  • 1
    (or, rather -- makefile code generates code later executed by a shell, but that's a strictly one-way street; variables set by the shell don't make their way back into make, or even into separate shell invocations that the same invocation of make starts later; also, unless you explicitly reconfigure it on this point, the shell make starts isn't bash). Commented Jul 25, 2019 at 18:05

1 Answer 1

3

Based on your example I don't know why you need to do this "within the rule". The answer to this question is absolutely vital to a correct response.

If your example is accurate and you're using make variables SERVICE and AVAILABLE_SERVICES then I don't see any reason that you can't put the variable assignment outside of the rule:

ifneq ($(filter $(SERVICE),$(AVAILABLE_SERVICES)),)
  export SA = $(SERVICE)
else
  export SA = default
endif
deploy:
        # do something ...
        # do something else

If the variables you're relying on are not make variables, then you have to implement the entire thing in the shell instead of using make constructs like ifneq, filter, etc.

If the latter remember that each logical line of a recipe is run in a different shell so if you want to set shell variables that are used in future statements you need to make those lines in the recipe one logical line (by adding a backslash at the end, which probably also requires you to add a shell statement separator ; between them).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the response, the reason is I don't want the if statement to be executed for all the rules - since it actually calls an API - which may/may not fail ... so don't want to get that list for any other rules other than deploy (just wanna execute if needed)
I don't know what you mean by "actually calls an API". Are you saying that the make variable AVAILABLE_SERVICES expands to a $(shell ...) function call? In any event, there's no way to use makefile ifeq constructs in a way that is NOT invoked while the makefile is parsed. These operations control which parts of the makefile are read in and which are skipped, so they must happen during the parsing stage. Unlike shell scripts, makefiles are read in completely before any rules are run (else how can make know it has all the prerequisites?)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.