Reputation: 118530
I want to disable builtin rules and variables as per passing the -r
and -R
options to GNU make, from inside the make file. Other solutions that allow me to do this implicitly and transparently are also welcome.
I've found several references to using MAKEFLAGS
, and had similar problems.
Upvotes: 82
Views: 36556
Reputation: 96256
Do this:
MAKEFLAGS += rR
$(foreach x,$(filter-out .% MAKE% SHELL CURDIR,$(.VARIABLES)) MAKEINFO,$(if $(filter default,$(origin $x)),$(eval override undefine $x)))
Here, rR
is equivalent to --no-builtin-rules --no-builtin-variables
.
--no-builtin-rules
seems to work properly, but --no-builtin-variables
is wonky.
--no-builtin-variables
prevents the recipes from seeing the variables, but if you try to access them outside of a recipe, they are still there.
That's what the second line is for. It manually undefines all built-in variables. (Same idea as in @JohnMarshall's answer, but without shell invocations.)
It removes all variables for which $(origin
)
reports default
, except that it ignores SHELL
,CURDIR
, and variables starting with .
and MAKE
(except MAKEINFO
), since those look useful.
Upvotes: 1
Reputation: 7005
Disabling the built-in rules is done by writing an empty rule for .SUFFIXES
:
.SUFFIXES:
Having erased the built-in rules, I'm not sure that erasing the built-in variables helps you much more than just remembering to set them yourself or not use them, but you could use something like
$(foreach V,
$(shell make -p -f/dev/null 2>/dev/null | sed -n '/^[^:#= ]* *=/s/ .*//p'),
$(if $(findstring default,$(origin $V)),$(eval $V=)))
...which is admittedly fairly crazy. If there is a way to get a list of the defined variables from within make (instead of shelling out to another make), it would be viable. As it is, it's not really much better than
CC=
CXX=
# etc, for each likely built-in variable
Upvotes: 54
Reputation: 5360
https://www.gnu.org/software/make/manual/make.html#Canceling-Rules
# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
# Makefile begins
main: main.c
cc main.c -o main
Upvotes: 19
Reputation: 19375
Disabling of built-in rules by writing an empty rule for .SUFFIXES
does not work if one then writes another .SUFFIXES
rule to add previously known suffixes - the built-in rules are re-enabled. Example: One wants to define rules for .c.i
and .i.o
, and to disable the built-in rule .c.o
. Writing
.SUFFIXES:
.SUFFIXES: .o .i .c
does not work - it does not prevent the built-in rule .c.o
from being applied.
The solution is the one employed by Marc Eaddy and documented in the GNU make manual, 10.5.6 Canceling Implicit Rules:
You can override a built-in implicit rule (or one you have defined yourself) by defining a new pattern rule with the same target and prerequisites, but a different recipe. When the new rule is defined, the built-in one is replaced. The new rule’s position in the sequence of implicit rules is determined by where you write the new rule.
You can cancel a built-in implicit rule by defining a pattern rule with the same target and prerequisites, but no recipe. For example, the following would cancel the rule that runs the assembler:
%.o : %.s
Upvotes: 11
Reputation: 1342
@hseldon has the right idea because .SUFFIXES doesn't cover the match-everything built-in implicit rules. However, I don't think his syntax is exactly right.
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
.SUFFIXES: .you .own .here
See http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Rules and http://www.gnu.org/software/make/manual/make.html#index-g_t_002eSUFFIXES-998
Upvotes: 39
Reputation: 35
################################################################
# DISABLE BUILT-IN RULES
#
.SUFFIXES:
MAKEFLAGS += -r
Upvotes: 1
Reputation: 1792
This works for me:
# Disable implicit rules to speedup build
.SUFFIXES:
SUFFIXES :=
%.out:
%.a:
%.ln:
%.o:
%: %.o
%.c:
%: %.c
%.ln: %.c
%.o: %.c
%.cc:
%: %.cc
%.o: %.cc
%.C:
%: %.C
%.o: %.C
%.cpp:
%: %.cpp
%.o: %.cpp
%.p:
%: %.p
%.o: %.p
%.f:
%: %.f
%.o: %.f
%.F:
%: %.F
%.o: %.F
%.f: %.F
%.r:
%: %.r
%.o: %.r
%.f: %.r
%.y:
%.ln: %.y
%.c: %.y
%.l:
%.ln: %.l
%.c: %.l
%.r: %.l
%.s:
%: %.s
%.o: %.s
%.S:
%: %.S
%.o: %.S
%.s: %.S
%.mod:
%: %.mod
%.o: %.mod
%.sym:
%.def:
%.sym: %.def
%.h:
%.info:
%.dvi:
%.tex:
%.dvi: %.tex
%.texinfo:
%.info: %.texinfo
%.dvi: %.texinfo
%.texi:
%.info: %.texi
%.dvi: %.texi
%.txinfo:
%.info: %.txinfo
%.dvi: %.txinfo
%.w:
%.c: %.w
%.tex: %.w
%.ch:
%.web:
%.p: %.web
%.tex: %.web
%.sh:
%: %.sh
%.elc:
%.el:
(%): %
%.out: %
%.c: %.w %.ch
%.tex: %.w %.ch
%: %,v
%: RCS/%,v
%: RCS/%
%: s.%
%: SCCS/s.%
.web.p:
.l.r:
.dvi:
.F.o:
.l:
.y.ln:
.o:
.y:
.def.sym:
.p.o:
.p:
.txinfo.dvi:
.a:
.l.ln:
.w.c:
.texi.dvi:
.sh:
.cc:
.cc.o:
.def:
.c.o:
.r.o:
.r:
.info:
.elc:
.l.c:
.out:
.C:
.r.f:
.S:
.texinfo.info:
.c:
.w.tex:
.c.ln:
.s.o:
.s:
.texinfo.dvi:
.el:
.texinfo:
.y.c:
.web.tex:
.texi.info:
.DEFAULT:
.h:
.tex.dvi:
.cpp.o:
.cpp:
.C.o:
.ln:
.texi:
.txinfo:
.tex:
.txinfo.info:
.ch:
.S.s:
.mod:
.mod.o:
.F.f:
.w:
.S.o:
.F:
.web:
.sym:
.f:
.f.o:
Put this in a file named disable_implicit_rules.mk and include
it in every makefile.
Upvotes: 7
Reputation: 18667
You could start the Makefile
with a #!
and call it something different so people don't try to use make
directly:
#!/usr/bin/make -rRf
# ...
This will cause horrific problems if GNU make is not the system make
. Maybe a wrapper script?
You can also read $(MAKEFLAGS)
and make sure the required flags are present.
Upvotes: 3