c - 执行 public01, public02, 时打印输出
问题描述
我有以下 Makefile:
CC = gcc
CFLAGS = -ansi -Wall -g -O0 -Wwrite-strings -Wshadow \
-pedantic-errors -fstack-protector-all
PROGS = public01 public02 public03 public04 public05 public06 shell_jr
.PHONY: all clean
all: $(PROGS)
clean:
rm -f *.o $(PROGS) a.out
$(PROGS): shell_jr.c
public0%:
shell_jr < public0%.in > output
cat output
每当输入 public0X 时,应该显示 shell_jr.c 的输出,当它使用来自 public0X.in 的输入运行时。public0% 标签是我试图做到这一点的尝试。但是,有3个问题。首先,我只能将 public0%.in 作为依赖项。这可以通过复制粘贴 public01、public02、...的单独命令来避免。其次,当我这样做并执行 make 时,命令会立即执行。如何确保在键入 public01 并按 Enter 之前不会执行该命令?
解决方案
首先,我只能将 public0%.in 作为依赖项。
我认为这部分是询问如何在配方中表达与所选目标相对应的输入文件的正确名称。模式规则的%
扩展仅在目标和先决条件中,而不是在配方中,但在任何 make
配方中,自动变量$@
表示正在构建的完整目标名称。由于想要的输入名称是通过将后缀附加.in
到目标名称来形成的,因此可以表示为$@.in
。
此外,您没有将public0%
目标命名为.PHONY
(与clean
and不同all
),但您对它们的规则实际上也不会创建它们。如果您同时尝试创建和显示这些文件,那么您还可以使用$@
将输出定向到所需文件。否则,您也应该将这些目标标记为.PHONY
.
此外,如果您打算(重新)创建这些文件而不管是否有任何更改,那么从先决条件列表中省略输入文件是合适的。但是,否则,将输入文件命名为先决条件将有助于make
跳过不必要的重新生成%public0%
文件。
其次,当我这样做并执行 make 时,命令会立即执行。如何确保在键入 public01 并按 Enter 之前不会执行该命令?
make
不是交互式的。如果要指定要构建的特定目标或目标,而不是默认目标,则将它们表示为make
命令行上的附加参数:
make public01
但是我认为您要解决的问题可能与您实际所说的不同。您的默认目标将构建所有在 中命名的目标$(PROGS)
,并且在先决条件不需要的情况下,make
以串行模式运行的 GNU 将尝试按照它们命名的顺序构建目标。你们public0%
所有人都依赖于该shell_jr
程序,但他们并未将其指定为先决条件。(它们确实将其命名shell_jr.c
为先决条件,但这实际上并不是直接依赖关系,并且将其指定为一个没有用处。)因此,make
将在尝试构建所有public0%
目标之前尝试构建shell_jr
.
正确的做法是表达正确的依赖关系。这个版本是这样做的,假设它们public0%
是实际构建的文件:
CC = gcc
CFLAGS = -ansi -Wall -g -O0 -Wwrite-strings -Wshadow \
-pedantic-errors -fstack-protector-all
PROGS = shell_jr
OUTPUTS = public01 public02 public03 public04 public05 public06
.PHONY: all clean
all: $(PROGS) $(OUTPUTS)
clean:
rm -f *.o $(PROGS) $(OUTPUTS)
# shell_jr is built according to a built-in rule (as was already the case)
public0%: public0%.in shell_jr
shell_jr < $@.in > $@
cat $@
请注意,public0%
仅当相应的输入文件已更改或shell_jr
需要重建时,才会重建(并显示)文件。如果您希望在没有任何更改的情况下构建和显示它们,那么您可以添加一个没有先决条件或配方的目标,并将其作为public0%
规则的先决条件:
public0%: public0%.in shell_jr FORCE
shell_jr < $@.in > $@
cat $@
FORCE:
.PHONY: FORCE
FORCE
每次make
运行都会认为目标已经重建,从而触发public0%
要重建的目标。
推荐阅读
- javascript - 获取 vanilla JS 中选择元素的前面(初始)和所选值
- python - 尝试加入并获取 select_related 中给出的无效字段名称:'audio_links'。选项有:(无)
- performance - 我如何减少网站的加载时间
- c - strsep() 用 '\n' 作为 C 中的分隔符
- c# - SoundEffect.DistanceScale - 如何在 2D 中计算比例?
- c# - WPF ComboBox 项与 XAML 值绑定
- entity-framework - Azure 弹性查询(外部数据源)和实体框架代码优先
- cordova - MediaRecorder - 如何“清除” blob 数据/创建新记录?
- windows - 覆盖文件实际上会覆盖它吗?
- reactjs - Jenkins 在生产服务器上自动构建 Github 存储库