makefile - GNU 制作特定于目标的变量,想要单个赋值,得到很多
问题描述
给定以下 GNU Makefile:
OBJS = a.o b.o
LIB = libX.a
$(LIB): $(OBJS)
$(AR) cr $@ $^
$(LIB): CPPFLAGS = $(shell P)
当我构建时$(LIB)
,我可以看到外部程序 P 被调用了两次,每次构建一次a.o
(b.o
我只是打印getpid()
到stderr
)。
就我而言, P 将始终产生相同的结果,因此 P 要求创建每个.o
. LIB
当然可以由许多 .o 组成,而且问题更糟。
有没有办法让特定于目标的变量只被评估一次,即为目标评估,$(LIB)
并且将 VALUE 逐字传递给先决条件配方(.o
from .c
)?还是我误解了他们的用法(我怀疑我是!)
通过反复试验,尝试了各种变量赋值语法,例如=
and :=
、 even 。::=
一遍又一遍地阅读手册。
解决方案
有没有办法让特定于目标的变量只被评估一次,即为目标评估,
$(LIB)
并且将 VALUE 逐字传递给先决条件配方(.o
from.c
)?还是我误解了他们的用法(我怀疑我是!)
文档似乎没有指定何时以及如何设置目标特定变量以构建受影响目标的先决条件的确切语义。对于您想要的行为,您最好的选择是使用简单的变量赋值(:=
或::=
),但您说这不起作用。 make
似乎表现得好像变量赋值分别包含在每个先决条件的规则中,这是有道理的,因为一般来说,不能保证所有先决条件都会一个接一个地构建或紧邻主要目标之前构建,在它们不是一个接一个地构建的地方,变量必须在两者之间恢复其全局值。
真的,我想鼓励您尽量减少对 GNU 特定功能的使用make
。它们中的每一个都是一种便利,而不是必需品,尽管偶尔,其中一些确实非常方便。您可以考虑改为部署 Autoconf +/- Automake 以(半)动态地将标志插入到您的 makefile 中。
但是,如果您必须$(shell)
在您的 makefile 中使用,并且您想确定该命令每次make
运行只执行一次,那么您最好的选择可能是在任何规则之外运行它。如果您不想修改全局 CPPFLAGS 则将结果存储在其他变量中:
OBJS = a.o b.o
LIB = libX.a
X_CPPFLAGS := $(shell P)
$(LIB): $(OBJS)
$(AR) cr $@ $^
$(LIB): CPPFLAGS = $(X_CPPFLAGS)
推荐阅读
- oracle - 在 APEX 的 SQL 命令中创建使用 APEX_JSON 的过程时,从 ORDS 返回错误 500
- vue.js - 如何修复块加载失败?
- node.js - @babel import _Object$defineProperty from "../../core-js/object/define-property" 的问题;
- jquery - 粘性导航栏未正确定位
- c++ - 确认在 TWS c++ API 中是否至关重要
- c# - 动态网络的最佳方法是什么?
- c# - 有没有办法将一个方法传递给 c# 中的另一个方法,最好的方法是什么?
- oop - 定义了 getter 和 setter 且没有后备变量的变量叫什么?
- javascript - JavaScript:我传入了一个列表,试图访问一个索引,它说变量未定义
- mysql - 我想减少节点 js rest api 中的一个属性