Reputation: 21
I have base Makefile for all my services, in some cases I want to use my default "test" target, in other cases I want to override\add to it. These are the files I have so far (and obviously its not working as expect..).
MakefileBase
test:
./.../run-tests.sh
Makefile
BASE_FILE := /path/to/MakefileBase
include ${BASE_FILE}
test:
@$(MAKE) -f $(BASE_FILE) test # un/comment this line in order to run the default tests.
# echo "custom test"
When I run the test with the first line commented out I get the following
Makefile:10: warning: overriding commands for target `test'
/.../MakefileBase:63: warning: ignoring old commands for target `test'
echo "no tests"
no tests
except of the warning it works as expected, the problem is when I try to use the parent function then I get the following errors:
Makefile:9: warning: overriding commands for target `test'
/.../MakefileBase:63: warning: ignoring old commands for target `test'
make[1]: test: No such file or directory
make[1]: *** No rule to make target `test'. Stop.
make: *** [test] Error 2
Upvotes: 2
Views: 6591
Reputation: 272
Actually, both answers so far are wrong or incomplete:
exit 0
in a rule will just exit the current shell (which runs only the exit 0
command, so it is a no-op in this case). So this won't override.
It's not true that you cannot override a command without warning. If it is not necessary that both targets have the same name, you can do:
MakefileBase
.PHONY: test-base
test-base:
echo base
%: %-base # handles cases where you don't want to override
Makefile1
include MakefileBase
.PHONY: test
test:
echo override
Makefile
include MakefileBase
.PHONY: test
test: test-base
echo append
As with double colon rules, the effects of each targets (on each other) have to be considered, especially if you move away from .PHONY
(for example, files considered up-to-date because the other rule just updated them).
BTW, I don't see the problem with your approach (aside from the warning). For me it worked fine.
Upvotes: 5
Reputation: 989
Hacky, but you can get add, and a limited form of override that can never be deeper than one override. Both use double colon rules.
add: use double colons on both rules
override: use double colons on both rules, appending command exit 0
to the last rule
# "addcmd" echoes "BA", "overridecmd" echoes "B"
addcmd ::
echo "A"
addcmd ::
echo "B"
overridecmd ::
echo "A"
overridecmd ::
echo "B"
exit 0
Upvotes: 0
Reputation: 100856
This is what double-colon rules are for:
test::
./.../run-tests.sh
and:
BASE_FILE := /path/to/MakefileBase
include ${BASE_FILE}
test::
@$(MAKE) -f $(BASE_FILE) test
This will "add to" an existing target. There is no way to override a target with a different recipe without incurring a warning.
If you want to do that the only way is to use variables to hold the recipe then override the variable value. For example:
test_recipe = ./.../run-tests.sh
test:
$(test_recipe)
and:
BASE_FILE := /path/to/MakefileBase
include ${BASE_FILE}
test_recipe = @$(MAKE) -f $(BASE_FILE) test
Upvotes: 0