C Make:在同一目标中编译对象文件两次
我在Makefile中遇到以下简单问题:C Make:在同一目标中编译对象文件两次,c,makefile,C,Makefile,我在Makefile中遇到以下简单问题: %.o:: %.c gcc -o $@ -c $< lib1.a: test.o ar -r $@ test.o rm *.o lib2.a: test.o ar -r $@ test.o rm *.o all: lib1.a lib2.a 我需要执行rm*.o操作,因为我希望每次都编译对象文件(在我真正的Makefile中,我有一个更复杂的用例,我使用不同的标志进
%.o:: %.c
gcc -o $@ -c $<
lib1.a: test.o
ar -r $@ test.o
rm *.o
lib2.a: test.o
ar -r $@ test.o
rm *.o
all: lib1.a lib2.a
我需要执行rm*.o
操作,因为我希望每次都编译对象文件(在我真正的Makefile中,我有一个更复杂的用例,我使用不同的标志进行编译)
我如何解决这个问题?似乎make
只编译一次对象文件
我用
.PHONY
代替了rm
,但它只编译了一次。Make是一个基于规则的系统。规则是声明性的:你声明你想从什么中构建什么,你不指定发生的顺序(除非你无法避免)。因此,一个好的Makefile是声明性的:所有结果都像在声明性编程语言中一样声明。它们就像Java中的final
变量:您将它们绑定到一个值,之后不会将它们重新分配到另一个值
Make也是基于文件的:它的“变量”、目标和先决条件都是文件
因此,如果你想构建两个不同的东西,不要用同一个名字来称呼它们!如果需要两个不同的
test.o
文件,请以不同的方式调用它们。这个问题将在您不需要尝试和说服make
它应该像命令式编程语言一样的情况下解决,而它是专门设计的。如果您想要一个命令式的构建规范,请使用shell脚本。您的makefile有点违反了make
逻辑,这就是为什么结果不是您所期望的:
- 在这里,您定义了两个目标(
和lib1.a
),它们具有共同的依赖关系:lib2.a
test.o
- 然后定义依赖于
和lib1.a
的规则lib2.a
(顺便说一句,应该是all
,但这不是问题).PHONY
all
,make
必须构建lib1.a
和lib2.a
。它们都依赖于test.o
,因此make
buildstest.o
一次,然后构建lib1.a
和lib2.a
,期望您定义的配方只构建这些文件,而不是别的
问题是您删除了lib1.a
和lib2.a
配方中的test.o
,虽然构建它们不需要此操作,但这是在清理而不是构建时要执行的操作
有两种解决方案:
clean
的.PHONY
规则)%.o::%.c
one),您甚至不需要考虑中间目标就可以实现这一点一次创建
.o
文件符合Make的工作方式,应该不会有问题(事实上,从时间消耗的角度来看,它不重复该步骤是件好事)。奇怪的是在运行ar
后立即将其删除。为什么要这样做?尝试为每个对象文件使用不同的名称。更好的是,将每组.o文件编译成单独的目录。为什么lib1.a
和lib2.a
包含相同的对象文件?你应该有一个libmy.a
!您应该在Makefile
中使用更多变量,就像这是我实际Makefile的简化版本一样。我尝试用一个公共对象文件和一些其他不同的文件创建不同的库。但是,对于某些库,我使用不同的标志编译公共对象文件。我想我确实可以按照@iharob的建议创建不同的对象文件。
gcc -o test.o -c test.c
ar -r lib1.a test.o
rm *.o
ar -r lib2.a test.o
ar: test.o: No such file or directory
make: *** [lib2.a] Error 1