I capture the intent of the Makefile in pseudo code, then indicate the issues I have. I'm looking for a Makefile which is more user friendly in a test environment. The correct usage of the Makefile is one of the below.
make CATEGORY=parser TEST=basic.
make ALL
If a user gives "JUST" the commands as indicated below, it should print a message saying "CATEGORY defined TEST undefined" and vice-versa
make CATEGORY=parser
make TEST=basic
I tried writing the Makefile in following ways, but it errors out:
help:
echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
echo" make ALL
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
else
echo "CATEGORY not defined"
endif
ifeq ($(CATEGORY_TEST_DEFINED), 1)
$(CATEGORY):
cd $(PROJ)/$(CATEGORY)
make -f test.mk $(TEST)
endif
ifdef ALL
$(ALL):
for i in `ls`
cd $$(i)
make all
endif
The questions I have are:
Whether the rules in a Makefile can be selective (using ifdef to select the rules and targets).
echo doesn't work. echo should help the user with correct usage.
The problem is that echo
belongs to the shell; Make can pass it to the shell in a command, but Make cannot execute it. Use info
instead:
ifdef CATEGORY
$(info CATEGORY defined)
else
$(info CATEGORY undefined)
endif
If you want the rules to be conditional:
ifdef CATEGORY
ifdef TEST
$(CATEGORY):
whatever
else
$(info TEST not defined)
else
$(info CATEGORY not defined)
endif
These lines are dubious:
help:
echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
echo" make ALL
You need a space between echo
and the string, and the string needs to be terminated:
help:
echo "Usage: make CATEGORY=<advanced|basic> TEST=<test-case>"
echo " make ALL"
These lines are dubious:
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
else
echo "CATEGORY not defined"
endif
Surely you need an endif
before the second else
? (Even if it is not syntactically mandatory, I'd recommend it.)
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
endif
else
echo "CATEGORY not defined"
endif
Additionally, make
only executes commands such as echo
is supposed to be when processing a target (rule). It won't execute echo
there; it will simply object that you cannot define commands without them being actions for a target. Despite everything that GNU Make adds to a makefile, the language in a makefile is a declarative language and not a procedural language.
Another way of handling this is to define default values for the macros:
CATEGORY = advanced
TEST = all
Define default values that do something semi-reasonable; let the user override the default if they want to. You can have a rule such as:
${CATEGORY}/${TEST}: ...dependencies...
...actions...
You can leave help
as the first rule. I have some directories where the first rule is:
null:
@echo "You must specify a target with this makefile!"
This is equivalent to what you have (except that make
does not echo the command before running it, so I only see the message instead of the echo command line and the message; that's the @
at work). The makefile this comes from also has a rule all
which is otherwise usually the most sensible first (default) rule.