Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile Rules and If Statements -- How?

I'm new to Makefiles so please bear with me.

I need to modify a Makefile so some rules call different utilities depending on a variable.

Right now, a rule looks like:

ci:
    [shell syntax for tool (A)]

But now I need ci to have a different syntax depending on the variable. So I define a global variable at the top of the file:

TOOL = toolA

or

TOOL = toolB

Ideally what I'd like is something like this, but obviously it doesn't work:

ifeq ($TOOL, toolA)
    ci:
        [syntax for tool (A)]
else
    ci:
        [syntax for tool (B)
endif

Does anyone know the best way to implement something like this properly?

Thanks!!

EDIT: The tool syntax is more complicated than one line. Sometimes its multiple lines and not just "toolA args etc etc". Sorry for the confusion!

like image 987
RaytheonLiszt Avatar asked Jun 14 '11 19:06

RaytheonLiszt


People also ask

What is a rule in makefile?

A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and the recipe to use to create or update the target.

What is $@ in makefile?

The file name of the target of the rule. If the target is an archive member, then ' $@ ' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ' $@ ' is the name of whichever target caused the rule's recipe to be run.

How do I write an if statement in makefile?

If the condition is true, make reads the lines of the text-if-true as part of the makefile; if the condition is false, make ignores those lines completely. It follows that syntactic units of the makefile, such as rules, may safely be split across the beginning or the end of the conditional.

How do you check if a variable is defined in makefile?

Check if variable is defined in a Makefilecheck_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2))))) __check_defined = \ $(if $(value $1),, \ $(error Undefined $1$(if $2, ($2)))) install: $(call check_defined, var1) $(call check_defined, var2) # do stuff here..


2 Answers

You're just missing some parentheses:

ifeq ($(TOOL), toolA)
...

P.S. You can make the conditional a little tighter (and remove a little redundancy):

ci:
ifeq ($(TOOL), toolA)
    [syntax for tool (A)]
else
    [syntax for tool (B)
endif
like image 200
Beta Avatar answered Oct 25 '22 17:10

Beta


Usually, you do that with a macro:

  # put tool A or tool B command line here
  TOOL=...

  ci:
       $(TOOL) args

That can be extended with something like a TOOLARGS macro, so something like

  ci:
       $(TOOL) $(TOOLARGS)

Then you can modify the makefile, or put the macros on the command line

  $ make TOOL=... TOOLARGS=...

If you want to encapsulate it, you could use an if to set the arguments.

like image 35
Charlie Martin Avatar answered Oct 25 '22 17:10

Charlie Martin