Disable make builtin rules and variables from inside the make file

27,995

Solution 1

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.

Solution 2

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

Solution 3

@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

Solution 4

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

Solution 5

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.

Share:
27,995
Matt Joiner
Author by

Matt Joiner

About Me I like parsimonious code, with simple interfaces and excellent documentation. I'm not interested in enterprise, boiler-plate, or cookie-cutter nonsense. I oppose cruft and obfuscation. My favourite languages are Go, Python and C. I wish I was better at Haskell. Google+ GitHub Bitbucket Google code My favourite posts http://stackoverflow.com/questions/3609469/what-are-the-thread-limitations-when-working-on-linux-compared-to-processes-for/3705919#3705919 http://stackoverflow.com/questions/4352425/what-should-i-learn-first-before-heading-to-c/4352469#4352469 http://stackoverflow.com/questions/6167809/how-much-bad-can-be-done-using-register-variables-in-c/6168852#6168852 http://stackoverflow.com/questions/4141307/c-and-c-source-code-profiling-tools/4141345#4141345 http://stackoverflow.com/questions/3463207/how-big-can-a-malloc-be-in-c/3486163#3486163 http://stackoverflow.com/questions/4095637/memory-use-of-stl-data-structures-windows-vs-linux/4183178#4183178

Updated on July 05, 2022

Comments

  • Matt Joiner
    Matt Joiner almost 2 years

    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.

  • Matt Joiner
    Matt Joiner over 13 years
    I think you want #!/usr/bin/env make -rRf?. Oh I see what you mean now.
  • Jack Kelly
    Jack Kelly over 13 years
    /usr/bin/env is probably better.
  • Matt Joiner
    Matt Joiner about 13 years
    This is nice, but a bit too hacky.
  • Brandon Bloom
    Brandon Bloom over 12 years
    I don't think this handles the built-in match anything rules
  • Victor Eijkhout
    Victor Eijkhout over 10 years
    That doesn't do it for me. I have a rule. % : foo.o bar.o and on execution make does "rm foo.o bar.o". That does not go away with your proposed flag setting.
  • Søren Løvborg
    Søren Løvborg almost 10 years
    It seems that in some versions of GNU Make, clearing .SUFFIXES disables built-in suffix rules but not pattern rules (see Brandon's answer). In my version of GNU Make (3.81) .SUFFIXES appears sufficient, though.
  • Søren Løvborg
    Søren Løvborg almost 10 years
    @VictorEijkhout: That's not caused by built-in rules, but by chaining of rules. Use .SECONDARY to prevent automatic removal.
  • Sebastian Schrader
    Sebastian Schrader over 7 years
    This won't work and yield /usr/bin/env: ‘make -rRf’: No such file or directory on many systems (such as e.g. Linux) as only a single optional argument is supported on the shebang line and no command splitting is done. See here.
  • rjh
    rjh almost 6 years
    On make 3.82, this still doesn't disable automatic rules like cp Sample Sample.out
  • Evan Carroll
    Evan Carroll over 5 years
    This is a duplicate of the answer above stackoverflow.com/a/8828716/124486
  • lucky
    lucky over 4 years
    Note to readers: .SUFFIXES: is not needed if you just want to do away with the built-in rules. MAKEFLAGS is all you need.
  • Spear
    Spear over 4 years
    @AndréChalella: not true in my case. Using both statements I get the fewest lines when doing "make -d xxx".
  • lucky
    lucky over 4 years
    @AxelBregnsbo strange, check the manual on the --no-builtin-rules section.
  • Jesper Matthiesen
    Jesper Matthiesen over 4 years
    For some reason, I can't make this work, although the following works: make --no-builtin-rules
  • Jaakko
    Jaakko over 4 years
    I remember this was a pain when I last did it.
  • PMN
    PMN about 3 years
    Using the same link you have mentioned, >SUFFIXES would be empty if no-builtin-rules is active: >The ‘-r’ or ‘--no-builtin-rules’ flag causes the default list of suffixes to be empty
  • PMN
    PMN about 3 years
    The ‘-r’ or ‘--no-builtin-rules’ flag causes the default list of suffixes to be empty, from : gnu.org/software/make/manual/html_node/Suffix-Rules.html
  • PMN
    PMN about 3 years
    This is the best answer, simple and complete, you can check it with make -p, look for # No implicit rules. and # No pattern-specific variable values.. Remove the MAKEFLAGS lines and you can see hell more output.
  • John Marshall
    John Marshall about 3 years
    @PMN: The question in this case is: “I know about the -r etc options, but is there a way to do this from inside the makefile”.
  • DaveC
    DaveC about 3 years
    Yes, the variable $(SUFFIXES) is empty when --no-builtin-rules is passed on the command line. On the contrary, it isn't empty when --no-builtin-rules is added to MAKEFLAGS inside the Makefile, but it doesn't mean that known suffixes aren't ignored. For example known suffixes can also be ignored by adding the rule .SUFFIXES: but it does not alter the variable $(SUFFIXES) either. Therefore I also believe that .SUFFIXES: is not needed when --no-builtin-rules is used (whether inside the Makefile or not)