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

发布于 2024-09-30 23:28:19 字数 535 浏览 3 评论 0 原文

我想根据传递 禁用内置规则和变量GNU make 的 -r-R 选项,来自 make 文件内部。也欢迎其他允许我隐式且透明地执行此操作的解决方案。

我发现 使用 MAKEFLAGS,并且有类似的问题。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

素染倾城色 2024-10-07 23:28:19

禁用内置规则是通过 为 < 编写一个空规则来完成的code>.SUFFIXES

.SUFFIXES:

删除了内置规则后,我不确定删除内置变量对您的帮助不仅仅是记住自己设置它们或不使用它们,但是你可以使用类似

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

......这无疑是相当疯狂的。如果有一种方法可以从 make 中获取已定义变量的列表(而不是转移到另一个 make),那么它是可行的。事实上,它并不比

CC=
CXX=
# etc, for each likely built-in variable

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
糖粟与秋泊 2024-10-07 23:28:19

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

MAKEFLAGS += --no-builtin-rules

.SUFFIXES:
.SUFFIXES: .you .own .here

请参阅 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

@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

四叶草在未来唯美盛开 2024-10-07 23:28:19

https://www.gnu.org/software/make/manual /make.html#取消规则

# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables

# Makefile begins
main: main.c
    cc main.c -o main

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
终遇你 2024-10-07 23:28:19

如果随后编写另一个 .SUFFIXES 规则来添加先前已知的后缀,则通过为 .SUFFIXES 编写空规则来禁用内置规则将不起作用 - 内置规则已重新启用。示例:想要为 .ci.io 定义规则,并禁用内置规则 .co。写入

.SUFFIXES:
.SUFFIXES: .o .i .c

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

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

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

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

<前><代码> %.o : %.s

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
审判长 2024-10-07 23:28:19

这对我有用:

# 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:

将其放入名为disable_implicit_rules.mk 的文件中,并将其包含在每个makefile 中。

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.

哭了丶谁疼 2024-10-07 23:28:19

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

#!/usr/bin/make -rRf
# ...

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

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

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.

水水月牙 2024-10-07 23:28:19
################################################################
# DISABLE BUILT-IN RULES
#
.SUFFIXES:
    MAKEFLAGS += -r
################################################################
# DISABLE BUILT-IN RULES
#
.SUFFIXES:
    MAKEFLAGS += -r
心房的律动 2024-10-07 23:28:19

执行此操作:

MAKEFLAGS += rR
$(foreach x,$(filter-out .% MAKE% SHELL CURDIR,$(.VARIABLES)) MAKEINFO,$(if $(filter default,$(origin $x)),$(eval override undefine $x)))

这里,rR 相当于--no-builtin-rules --no-builtin-variables

--no-builtin-rules 似乎工作正常,但 --no-builtin-variables 很不稳定。

--no-builtin-variables 阻止配方看到变量,但如果您尝试在配方之外访问它们,它们仍然存在。

这就是第二行的用途。它手动取消定义所有内置变量。 (与 @JohnMarshall 的回答中的想法相同,但没有 shell 调用。)

它会删除 $( origin ) 报告 default,但它会忽略 SHELLCURDIR 以及以 < 开头的变量code>. 和 MAKEMAKEINFO 除外),因为它们看起来很有用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文