1

我有一个makefile,它假设为目录中的每个file.csv 重复执行一次ac 代码(BootstrapCL.c)。对于每次执行,它应该输入 c 代码(作为 argv) 2 字符串:当前执行中使用的输入 csv 文件的名称,带扩展名和不带扩展名。这是makefile的内容:

SRCS := $(wildcard *.csv)
BINS := $(SRCS:%.csv=%)

all: ${BINS}

%: BootstrapCL.c
    gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
    ./BootstrapCL $@.csv $@

问题是,在执行完所有的 csv 文件组之后(我只想执行 ${BINS} 列表中的目标),它还使用“all”目标运行最后一次执行。当然,我的文件夹中没有任何 all.csv 文件;我想我以错误的方式使用 $@,但我不明白为什么以及如何解决这个问题,知道吗?

4

3 回答 3

1

问题是您没有的配方,并且没有匹配任何东西all的规则当 Make 完成了先决条件 ( ) 后,它会尝试构建,去寻找适合的配方,然后找到.%${BINS}all%

有(至少)两种方法可以解决这个问题。快速而肮脏的方法是添加一个(空)配方all

all: ${BINS}
    @:

另一种方法,在我看来更好,是收紧第二条规则:

BINS := $(SRCS:%.csv=%.phony)

all: ${BINS}

%.phony: BootstrapCL.c
    gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
    ./BootstrapCL $*.csv $*

为了整洁,我建议您还添加以下行:

.PHONY: $(BINS)

让 Make 知道.phony目标不是要构建的真实文件。

其他一些小的改进是可能的。我会考虑BootstrapCL它是否会产生一个可以用作真正目标的文件。

于 2021-01-29T13:16:49.370 回答
1

我对解决方案的看法与 Beta 略有不同:

SRCS := $(wildcard *.csv)
BINS := $(SRCS:%.csv=%)

# All rule - requires binaries to be generated. This does not generate anything, therefore it is PHONY
.PHONY: all
all: ${BINS}

# Generates the binaries - requires BootstrapCL exe to be generated first
${BINS}: BootstrapCL
    ./BootstrapCL $@.csv $@

# Generates BootstrapCL
BootstrapCL:
    gcc -Wall BootstrapCL.c  -lm -o BootstrapCL

据我所知 - 您需要编译 BootstrapCL.c 一次以生成 BootstrapCL 可执行文件。然后使用它生成多个二进制文件 - 一个用于 eacn .csv 文件。

所以反过来:

  • 您有一个all需要 BINS 的目标。
  • 您有一个BINS生成 BIN 的目标,但首先需要 BootstrapCL - 这将为每个 .csv 文件运行一次。
  • 您有一个BootstrapCL生成 BootstrapCL 可执行文件的目标 - 这将只运行一次。
于 2021-01-29T13:34:14.797 回答
1

这条%规则太笼统了,可以捕获所有内容,甚至尝试重建 Makefile 本身。BootstrapCL此外,它每次都编译,这似乎没有必要:

$ make
gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
./BootstrapCL Makefile.csv Makefile
gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
./BootstrapCL foo.csv foo
gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
./BootstrapCL bar.csv bar
gcc -Wall BootstrapCL.c  -lm -o BootstrapCL
./BootstrapCL all.csv all

我会使用模式规则生成二进制文件,因为如果 .csv 文件发生更改,这也将重建二进制文件。我还将BootstrapCL生成与不同的规则分开,只编译一次,但将其保留在依赖项列表中,以便目标在BootstrapCL更改时重新生成它们:

$ cat Makefile
SRCS := $(wildcard *.csv)
BINS := $(SRCS:%.csv=%)

all: ${BINS}

BootstrapCL: BootstrapCL.c
        gcc -Wall $< -lm -o $@

%: %.csv BootstrapCL
        ./BootstrapCL $< $@

输出:

$ make
gcc -Wall BootstrapCL.c -lm -o BootstrapCL
./BootstrapCL foo.csv foo
./BootstrapCL bar.csv bar
于 2021-01-29T13:43:47.603 回答