从make文件中禁用make内置规则和变量

Mat*_*ner 52 gnu makefile build gnu-make

我想禁用内置规则和变量,因为从make文件中传递-r-R选项到GNU make.允许我隐式和透明地执行此操作的其他解决方案也是受欢迎的.

我发现了几个使用的参考MAKEFLAGS,并有类似的问题.

Joh*_*all 32

禁用内置规则是通过为以下内容编写空规则来完成的.SUFFIXES:

.SUFFIXES:
Run Code Online (Sandbox Code Playgroud)

删除了内置规则后,我不确定删除内置变量会不仅仅是记住自己设置或不使用它们,而是可以使用像

$(foreach V
    $(shell make -p -f/dev/null 2>/dev/null | sed -n '/^[^:#= ]* *=/s/ .*//p'),
    $(if $(findstring default,$(origin $V)),$(eval $V=)))
Run Code Online (Sandbox Code Playgroud)

......这无疑是相当疯狂的.如果有办法从make中获取已定义变量的列表(而不是炮轰到另一个make),那么它将是可行的.事实上,它并不比它好多少

CC=
CXX=
# etc, for each likely built-in variable
Run Code Online (Sandbox Code Playgroud)

  • 我认为这不会处理内置的[匹配任何规则](http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Rules) (2认同)
  • [看来](https://savannah.gnu.org/bugs/?20501)在某些版本的GNU Make中,清除“.SUFFIXES”会禁用内置的_后缀规则_,但不会禁用_模式规则_(请参阅布兰登的答案)。不过,在我的 GNU Make (3.81) 版本中,`.SUFFIXES` 似乎足够了。 (2认同)
  • 在 make 3.82 上,这仍然不会禁用像“cp Sample Sample.out”这样的自动规则 (2认同)

Bra*_*oom 26

@hseldon有正确的想法,因为.SUFFIXES没有涵盖匹配 - 所有内置的隐式规则.但是,我不认为他的语法是完全正确的.

MAKEFLAGS += --no-builtin-rules

.SUFFIXES:
.SUFFIXES: .you .own .here
Run Code Online (Sandbox Code Playgroud)

http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Ruleshttp://www.gnu.org/software/make/manual/make.html#index-g_t_002eSUFFIXES-998

  • @VictorEijkhout:这不是由内置规则引起的,而是由[规则链接]引起的(https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html).使用`.SECONDARY`来防止自动删除. (3认同)

Jaa*_*kko 9

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
Run Code Online (Sandbox Code Playgroud)


Mar*_*ddy 7

这对我有用:

# 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:
Run Code Online (Sandbox Code Playgroud)

将它放在名为disable_implicit_rules.mk的文件中,并将include其放在每个makefile中.


Arm*_*ali 5

.SUFFIXES如果编写另一个.SUFFIXES规则以添加以前已知的后缀,则通过编写空规则来禁用内置规则不起作用- 重新启用内置规则.示例:想要为.c.i和定义规则.i.o,并禁用内置规则.c.o.写作

.SUFFIXES:
.SUFFIXES: .o .i .c
Run Code Online (Sandbox Code Playgroud)

不起作用 - 它不会阻止应用内置规则.c.o.

解决方案是Marc Eaddy使用的解决方案,并在GNU make手册中有记录,10.5.6取消隐式规则:

您可以通过定义具有相同目标和先决条件但具有不同配方的新模式规则来覆盖内置隐式规则(或您自己定义的规则).定义新规则时,将替换内置规则.新规则在隐式规则序列中的位置取决于您编写新规则的位置.

您可以通过定义具有相同目标和先决条件但没有配方的模式规则来取消内置隐式规则.例如,以下将取消运行汇编程序的规则:

    %.o : %.s
Run Code Online (Sandbox Code Playgroud)


Jac*_*lly 3

您可以以Makefilea开头#!并将其命名为不同的名称,这样人们就不会尝试make直接使用:

#!/usr/bin/make -rRf
# ...
Run Code Online (Sandbox Code Playgroud)

如果 GNU make 不是系统,这将导致可怕的问题make。也许是一个包装脚本?

您还可以阅读$(MAKEFLAGS)并确保存在所需的标志。

  • 我想你想要 `#!/usr/bin/env make -rRf`?。哦,我现在明白你的意思了。 (3认同)
  • 这在许多系统(例如 Linux)上不起作用并产生 `/usr/bin/env: 'make -rRf': No such file or directory`,因为 shebang 行仅支持单个可选参数,并且不支持命令分割完成。请参阅[此处](https://en.wikipedia.org/wiki/Shebang_(Unix)#Portability)。 (3认同)