如何使用目标相关的编译器通过相同的规则制作多个目标?
How to make multiple targets by the same rule using target-dependent compilers?
假设我想验证 hello.c
与多个编译器的兼容性。如何使用 Makefile 来实现?
这是我为此编写的 Makefile。
# Makefile, version 1.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello
./hello
rm -f hello
hello: hello.c
$(CC) hello.c -o hello
如果我运行make test_gcc
或test_clang
,一切正常。但是,make all
导致以下结果。
./hello
Hello, world!
rm -f hello
touch hello.c
./hello
make : ./hello : command not found
make: *** [Makefile:10 : test_clang] Error 127
所以 hello
没有为 test_clang
重新制作。这对像我这样的 Makfile 初学者来说似乎是这样。
问题:在我的Makefile中,test_clang
依赖于hello
,当test_gcc
完成时,它已被删除。那么为什么 make
不在 运行 宁 ./hello
之前再次生成它?
我的尝试:
为了解决这个问题,我尝试了以下修改,在test_gcc
或test_clang
之后触及hello.c
。还是不行,还是一样的问题
# Makefile, version 2.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello hello.c
./hello
rm -f hello
touch hello.c
hello: hello.c
$(CC) hello.c -o hello
按照@HolyBlackCat 的建议,我也尝试了以下方法。
# Makefile, version 3.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello_$(CC)
./hello_$(CC)
rm -f hello_$(CC)
hello_$(CC): hello.c
$(CC) hello.c -o hello_$(CC)
make all
的输出是
gcc hello.c -o hello_gcc
./hello_gcc
Hello, world!
rm -f hello_gcc
./hello_clang
make : ./hello_clang : commande not found
make: *** [Makefile:13 : test_clang] Error 127
这更奇怪 --- hello_clang
从未被制作过,即使它是(仅)被 test_clang
要求的。
为方便起见,这里是我用于测试的标准hello.c
。
/* hello.c */
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
return 0;
}
非常感谢您提出任何建议。如果您对我的 Makefile 进行一般性评论,而不一定是针对我提出的问题,我们也将不胜感激。我真的是初学者
查看特定于目标的变量的文档:很明显,特定于目标的变量仅在配方中生效。您不能在先决条件中使用它们,当然也不能在定义目标时使用它们。
在没有目标特定变量的情况下执行此操作可能更简单,只需使用模式规则即可:
TEST = test_gcc test_clang
.PHONY: all
all: $(TEST)
test_%: hello_%
./$<
hello_%: hello.c
$* $< -o $@
(我不知道你为什么在测试后立即删除二进制文件,在这个版本中,所以我删除了它)。
假设我想验证 hello.c
与多个编译器的兼容性。如何使用 Makefile 来实现?
这是我为此编写的 Makefile。
# Makefile, version 1.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello
./hello
rm -f hello
hello: hello.c
$(CC) hello.c -o hello
如果我运行make test_gcc
或test_clang
,一切正常。但是,make all
导致以下结果。
./hello
Hello, world!
rm -f hello
touch hello.c
./hello
make : ./hello : command not found
make: *** [Makefile:10 : test_clang] Error 127
所以 hello
没有为 test_clang
重新制作。这对像我这样的 Makfile 初学者来说似乎是这样。
问题:在我的Makefile中,test_clang
依赖于hello
,当test_gcc
完成时,它已被删除。那么为什么 make
不在 运行 宁 ./hello
之前再次生成它?
我的尝试:
为了解决这个问题,我尝试了以下修改,在test_gcc
或test_clang
之后触及hello.c
。还是不行,还是一样的问题
# Makefile, version 2.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello hello.c
./hello
rm -f hello
touch hello.c
hello: hello.c
$(CC) hello.c -o hello
按照@HolyBlackCat 的建议,我也尝试了以下方法。
# Makefile, version 3.
# It tests hello.c using multiple compilers.
TEST = test_gcc test_clang
.PHONY: $(TEST) all
all: $(TEST)
test_gcc: CC = gcc
test_clang: CC = clang
$(TEST): hello_$(CC)
./hello_$(CC)
rm -f hello_$(CC)
hello_$(CC): hello.c
$(CC) hello.c -o hello_$(CC)
make all
的输出是
gcc hello.c -o hello_gcc
./hello_gcc
Hello, world!
rm -f hello_gcc
./hello_clang
make : ./hello_clang : commande not found
make: *** [Makefile:13 : test_clang] Error 127
这更奇怪 --- hello_clang
从未被制作过,即使它是(仅)被 test_clang
要求的。
为方便起见,这里是我用于测试的标准hello.c
。
/* hello.c */
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
return 0;
}
非常感谢您提出任何建议。如果您对我的 Makefile 进行一般性评论,而不一定是针对我提出的问题,我们也将不胜感激。我真的是初学者
查看特定于目标的变量的文档:很明显,特定于目标的变量仅在配方中生效。您不能在先决条件中使用它们,当然也不能在定义目标时使用它们。
在没有目标特定变量的情况下执行此操作可能更简单,只需使用模式规则即可:
TEST = test_gcc test_clang
.PHONY: all
all: $(TEST)
test_%: hello_%
./$<
hello_%: hello.c
$* $< -o $@
(我不知道你为什么在测试后立即删除二进制文件,在这个版本中,所以我删除了它)。