- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下 Makefile
:
.SUFFIXES:
.SUFFIXES: .c.o
.PHONY: all
all: foo.o
foo.o: foo.h bar.h xyzzy.h
%.o: %.c
@printf "prerequisites of %s are %s\n" $@ "$^"
除了foo.o
,所有文件都存在,输出为:
prerequisites of foo.o are foo.c foo.h bar.h xyzzy.h
正确地,自动变量 $^
为我们提供了所有先决条件,包括从其他规则中规定的依赖项中获得的条件。
让我们将规则本身给出的先决条件称为主要先决条件,并将来自其他依赖项的先决条件称为次要先决条件。
以上,主要先决条件是:
foo.c
次要的是:
foo.h bar.h xyzzy.h
类别很重要,因为主要先决条件是规则实际使用的对象,构建程序需要这些对象。次要先决条件仅涉及增量构建的正确触发,而不涉及完整构建。即使我们删除依赖行,从头开始的完整构建也可以工作:
foo.o: foo.h bar.h xyzzy.h
这反射(reflect)在我们的 Makefile
结构中。我们通常不会使用如下规则编写 Makefiles
:
foo.o: foo.c foo.h bar.h xyzzy.h
# commands
foo.c
之后的额外先决条件在其他地方被分解出来,通常是一个完全独立的依赖 makefile,由工具生成,并且可以完全删除,而不会影响执行完整操作的能力从头开始构建。
问题是:我们如何才能只获得主要先决条件的列表,而不包括次要先决条件?
这应该可以通过通用方式实现,无需任何硬编码。例如,如果我将一些食谱行定义为宏,它们可以在多个规则中重复使用。
define RULE_BODY
@printf "the primary prerequisites of target %s are %s\n" $@ [what goes here?]
endef
%.o: %.c
$(call RULE_BODY)
我不想将参数传递给 RULE_BODY,因为它应该“只知道”,就像它知道目标和全部先决条件一样。
请注意,模式规则的使用是转移注意力:我们可以将 %.o: %.c
替换为 foo.o: foo.c
。
最佳答案
一个可能的解决方案是添加一个中间依赖节点,它捕获次要先决条件,并将它们表示为单个先决条件。虚假先决条件具有某种可识别的词汇形式,可以根据该形式将其过滤掉:
概念验证,紧密基于问题中的 Makefile
:
.SUFFIXES:
.SUFFIXES: .c.o
all: foo.o
secondary_foo.o: foo.h bar.h xyzzy.h
echo $^ > $@
foo.o: secondary_foo.o
define RULE_BODY
@printf "prerequisites of %s are %s\n" $@ "$^"
@printf "primary prerequisites of %s are %s\n" $@ "$(filter-out secondary_$@,$^)"
@printf "secondary prerequisites of %s are %s\n" $@ "$(shell cat secondary_$@)"
endef
%.o: %.c
$(call RULE_BODY)
touch $@
输出:
prerequisites of foo.o are foo.c secondary_foo.o
primary prerequisites of foo.o are foo.c
secondary prerequisites of foo.o are foo.h bar.h xyzzy.h
touch foo.o
不幸的是,构建目录中散落着这些中间文件。即使以其他方式处理次要先决条件的传播,secondary_foo.o
文件仍然不能成为虚假目标;至少它必须是一个空的时间戳文件。
以下替代解决方案更为复杂,需要计算变量、eval
,并使用技巧将依赖项存储在用于生成规则的变量中。但是,它的优点是不会生成时间戳文件的激增。
.SUFFIXES:
.SUFFIXES: .c.o
OBJS := foo.o bar.o
all: $(OBJS)
# These variables give secondary dependencies for the objectg files,
# in place of rules. These would typeically be "farmed out" to
# a machine-generated dependency makefile which is included:
DEP_foo.o := foo.h bar.h xyzzy.h
DEP_bar.o := bar.h xyzzy.h
define RULE_BODY
@printf "\n"
@printf "prerequisites of %s are %s\n" $@ "$^"
@printf "primary prerequisites of %s are %s\n" $@ "$(filter-out $(DEP_$@),$^)"
@printf "secondary prerequisites of %s are %s\n" $@ "$(DEP_$@)"
endef
%.o: %.c
$(call RULE_BODY)
# Now the trickery: generate the dependency rules from OBJS and DEP_ vars:
# $(NL) provides newline, so we can insert newline into eval expansions
define NL
endef
# For each object <obj>, generate the rule <obj>: $(DEP_<obj>)
$(eval $(foreach obj,$(OBJS),$(obj): $(DEP_$(obj))$(NL)))
输出:
prerequisites of foo.o are foo.c foo.h bar.h xyzzy.h
primary prerequisites of foo.o are foo.c
secondary prerequisites of foo.o are foo.h bar.h xyzzy.h
prerequisites of bar.o are bar.c bar.h xyzzy.h
primary prerequisites of bar.o are bar.c
secondary prerequisites of bar.o are bar.h xyzzy.h
缺点是必须将任何额外的依赖项插入到变量中,而不是通过普通规则断言。例如,假设我们想要在 config.make
makefile 被触及时重新编译所有的 $(OBJS)
。我们不能只这样做:
$(OBJS): config.make # Oops, config.make is now considered primary
相反,我们坚持使用 DEP_
变量方案并按如下方式进行:
$(eval $(foreach obj,$(OBJS),DEP_$(obj) += config.make$(NL)))
换句话说,遍历$(OBJS)
,并为每个添加的
,后跟一个换行符,然后 DEP_
变量生成一个+=
变量赋值>config.makeeval
整个事情就好像它是 Makefile
文本一样。
当上面的 eval 被插入到我们的 Makefile
中时(在现有的 eval
之前,而不是之后)输出显示 config.make
已作为次要先决条件添加到 foo.o
和 bar.o
中:
prerequisites of foo.o are foo.c foo.h bar.h xyzzy.h config.make
primary prerequisites of foo.o are foo.c
secondary prerequisites of foo.o are foo.h bar.h xyzzy.h config.make
prerequisites of bar.o are bar.c bar.h xyzzy.h config.make
primary prerequisites of bar.o are bar.c
secondary prerequisites of bar.o are bar.h xyzzy.h config.make
这是一个可行的解决方案,它避免了临时文件,但对于 Makefile
维护者来说更难理解。
另请注意,由于 GNU Make 允许在变量名中使用句点和斜杠,因此类似以下内容不是问题:
DEP_libs/parser/scan.o := config.h libs/parser/parser.h ...
在规则中,libs/parser/scan.o
是 $@
目标,$(DEP_$@)
很好地给出了我们 config.h libs/parser/parser.h ...
。
最后,请注意依赖生成器可以生成代码并将其粘贴到依赖生成文件中,而不是 eval
行。也就是说,按照这些行生成文件:
DEP_foo.o := foo.h bar.h xyzzy.h config.make # config.make tacked on
foo.o: $(DEP_foo.o) # also generated
DEP_bar.o := ... # and so forth
bar.o: $(DEP_bar.o)
关于makefile - GNU 使 : obtain list of primary prerequisites of a rule,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27406585/
在 makefile 中,我可以从另一个规则调用一个规则吗? 类似于: rule1: echo "bye" rule2: date rule3: @ec
我想创建一个只匹配外部链接的 CSS 选择器。问题是它似乎不适用于 :not() 中的多个规则。我不能使用多个 not ( example: ":not():not()") 因为那变成了 ||而不是
我正在动态创建 CSS 动画,所以我需要在我的文档中插入一个 CSS 计时函数。如: @-webkit-keyframes slide { from { -webkit-transfo
错误内容: Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): HookW
我有这样的文件结构: ---- _base-map.scss ---- _child-map-1.scss ---- _child-map-2.scss ---- _child-map-3.scss
我正在利用 engine.Host 类创建自己的规则引擎实例,并通过 JSON 文件加载规则并调用 set_rulesets() 方法。这一切都运行良好。 持久规则:https://pypi.org/
在无服务器(https://www.serverless.com/framework/docs/providers/aws/events/event-bridge),的EventBridge文档中提到
在无服务器(https://www.serverless.com/framework/docs/providers/aws/events/event-bridge),的EventBridge文档中提到
系统要求我使用最常用的网络规则和应用程序规则配置 Azure 防火墙策略规则集合。 我收集了以下详细信息,其中捕获了最常用的网络规则和应用程序规则。但是我不确定我是否遗漏了任何被认为是最常见的规则?
我想做的是在运行时从 ABNF 语法文件创建一个解析器。我已经在 qi::grammar 中实现了所有 ABNF 规则,如下所示: typedef /*qi::rule or struct conta
对于复杂的多边形(即:自相交),选择缠绕填充规则还是奇偶填充规则会影响多边形的填充方式。 但对于非相交多边形,缠绕或奇偶填充规则之间是否存在任何性能差异。我知道这将是特定于实现的,但哪种算法对于非复杂
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 8 个月前
我正在尝试将 TypeScript 编译添加到现有的 Javascript 项目中。 AFAIK 这应该是可能的(甚至很容易),并且您可以通过代码库逐步传播 TS。不幸的是,这不是我所看到的——在添加
尝试将 Firebase 部署到其托管服务时。我还使用 firebase 工具来发布安全规则。我看到此错误消息: $ firebase deploy Security Rules Error - s
我在使用 ANTLR4 解析某些 SQL 类型的字符串时遇到问题。解析后的字符串是: WHERE a <> 17106 AND b BETWEEN c AND d AND e BTW(f, g) 这是
我已经在 Android 中创建了一个模块以在我的主应用程序中使用,并且似乎有两个文件Consumer-rules.pro 和 proguard-rules.pro。 我想了解以下内容 所有模块代码都
我正在尝试在另一个自定义规则中加载自定义规则,这两个规则均由 Parasoft 规则向导创建。 以下代码是作为方法放在调用规则中的python片段: def somePythonMethod(node
像许多其他问题一样,我正在尝试使用 Boost.Spirit.Qi 将简单语法解析为结构树。 我会尽量提炼我正在尝试做的事情,以尽可能最简单的情况。我有: struct Integer { int
我的samtools_dup规则存在一些问题。 它在/data/mypipeline.smk的第201行中显示“SyntaxError: 规则samtools_dup中的run/shell/scrip
有人可以向我解释一下这两种情况下负载均衡器(v2)后端实际发生的情况吗: 应用入站 NAT 规则。 应用负载平衡规则。 最佳答案 当您有 1 台后端服务器或者您知道要访问哪个后端服务器时,您将使用 N
我是一名优秀的程序员,十分优秀!