C makefile跳过了隐式规则?
我有一个用于编译一些C源文件的Makefile,并将输出放在不同的构建目录中,它看起来有点像下面的Makefile:C makefile跳过了隐式规则?,c,makefile,C,Makefile,我有一个用于编译一些C源文件的Makefile,并将输出放在不同的构建目录中,它看起来有点像下面的Makefile: OBJDIR=/home/test/alpha SRCDIR=/home/test/beta # make variable will be exanded when used (and not at declaration) OBJECTS:= $(addprefix $(OBJDIR), $(notdir $(patsubst %.c,%.o,$(wildcard $
OBJDIR=/home/test/alpha
SRCDIR=/home/test/beta
# make variable will be exanded when used (and not at declaration)
OBJECTS:= $(addprefix $(OBJDIR), $(notdir $(patsubst %.c,%.o,$(wildcard $(SRCDIR)/*.c))))
SOURCES:=$(wildcard $(SRCDIR)/*.c))
.PHONY: copySourcesOver linkSources sharedLibrary
copySourcesOver: $(SOURCES)
cp $(SOURCES) $(OBJDIR)/
# pattern
$(OBJECTS)/%.o : $(OBJECTS)/%.c
gcc -fPIC $< -o $@
linkSources: $(OBJECTS)
gcc -shared -o libshared.so $@
sharedLibrary: copySourcesOver \
linkSources \
我没有规则来制作$(对象)
。有趣的是,当我第二次创建这个目标时,我没有得到这个makefile错误,我得到了共享库
我做了一些研究,发现Makefile没有扩展虚假目标的隐式规则,这就是为什么我将linkSources
从虚假目标更改为普通文件的原因。但不幸的是,这并不能解决问题
我不明白为什么只有在第二次运行makesharedlibrary时才执行该模式,make分两个阶段执行。在第一阶段,它检查哪些目标已过时,需要更新。在第二阶段,它执行更新目标的命令。这意味着它会在实际复制源文件之前检查对象文件是否是最新的 因此,它检查并确定对象文件是最新的,然后将(更新的)源文件复制到
$(OBJDIR)
关于这个问题,有一些很好的读物。引用:
# pattern
$(OBJECTS)/%.o : $(OBJECTS)/%.c
gcc -fPIC $< -o $@
左侧的模式通过将对象的$(SRCDIR)
部分重写为$(OBJDIR)
来匹配您在对象中计算的任何一个对象文件模式
顺便说一下,看看这个模式规则如何轻松地执行反向重写?左侧的匹配将转换为右侧的.c
先决条件。查看规则如何不使用notdir
或addprefix
?您可以在计算对象时执行相同的操作(相反)。放下notdir
和addprefix
并使用单个patsubst
变换每个路径
此外,我还消除了重复的通配符。首先获取源
,然后从源计算对象
最后,当对象目录不存在时,在新签出中如何工作?您需要一些mkdir-p
。gcc-o foo/bar.o
不会创建foo
目录。除了下面的答案指出的内容外,如果您使用多个作业(-j
),您的生成文件也会中断;不能保证先决条件是按顺序执行的,如果一个先决条件依赖于另一个先决条件,那么就在makefile中表达出来。这一点很好。我将添加所有依赖项有些规则不将其目标声明为其目标,或将其依赖项声明为其依赖项,因此,make
检查规则是否必须运行不能正常工作。因此,在阅读文档后,我可以得出结论:OBJDIR=/home/test/alpha和SRCDIR=/home/test/beta,它们的右侧将延迟扩展。$(对象)不会在第一次运行makefile时展开,只会在第二次运行时展开。关键信息位于底部,规则定义
。立即检查规则sharedLibrary:copySourcesOver linkSources
。检查linkSources
不会导致任何操作,因为文件是最新的(请记住,更新的文件尚未复制),而检查copySourcesver
会导致任何更新的源文件的副本。第一个目标copySourcesver会将源文件复制到对象目录。是的,我同意,我已将其更改为静态模式规则,$(对象):%.o:%.c是否可以在对象目录根本不存在的情况下运行Makefile?请问一个问题,什么是反向重写?“反向重写”与规则的作用相反:规则与左侧的.o模式与目标匹配,然后将其重写为右侧的.c先决条件。这与您从源计算.o对象时所做的操作相反。基本上,模式规则是执行patsubs(leftpat、righpat、target)
。不,在这种情况下,对象目录预先存在,这是makefile变量OBJDIR。我明白你的意思,我会在另一个不同的地方做同样的事情
# pattern
$(OBJECTS)/%.o : $(OBJECTS)/%.c
gcc -fPIC $< -o $@
$(OBJDIR)/%.o : $(SRCDIR)/%.c