正确使用makefile

时间:2012-10-16 10:23:28

标签: c++ compilation makefile

所以,我试图理解makefile。此时我有一个带有一些模块的项目,这些模块或多或少都不依赖于彼此。

我的目录树是这样的:

root/
- Source/ <-- referenced as $(INPUTPATH)
- Build/ <-- referenced as $(BUILDPATH)
- Release/ <-- referenced as $(OUTPUTPATH)
- Makefile

我希望Source /上的源( .cpp / .h),Build /上的对象,以及Release /*上的可执行文件。

所以,我的想法是有几个不同的目标,并像这样使用它们:

all: maps auxiliars methods
    @echo "linking...";\
    $(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o ${OUTPUTPATH}/MainProgram

dependency1: $(INPUTPATH)/foo.cpp
    @echo "compiling ArbPrecision...";\
    cd ${BUILDPATH};\
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$?

dependency2: dependency1 $(INPUTPATH)/bar.cpp
    @echo "compiling saddleConstructor...";\
    cd ${BUILDPATH};\
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/bar.cpp

maps: dependency2 $(INPUTPATH)/*Map.cpp
    @echo "compiling maps...";\
    cd ${BUILDPATH};\
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/*Map.cpp
... (auxiliars and methods)

$ CINCLUDE和CFLAGS只是标题和外部库等编译器。

一切都近乎完美:在每个目标上,它要求其他目标的依赖关系,以及源上的* cpp。如果不存在,则调用目标并编译* cpp。创建可执行文件时没有错误。

但是,如果我两次调用“make”,编译所需的时间在第一次和第二次都是相同的,即使我没有对源进行任何更改。所以,显然,我并没有把依赖关系放在正确的位置。

有人能指出我执行此编辑的正确方向吗?我做错了什么,我不知道它是什么。

谢谢, 乔治

1 个答案:

答案 0 :(得分:3)

Make期望使用文件。对于每个规则,它检查是否存在由该规则(1)命名的目标文件,并且(2)是最新的(即,在其任何依赖性之后修改)。如果文件不是最新的,那么它会执行规则以使其更新。

因此,当您编写makefile时,当您运行make时,Make会执行以下操作:

  • all是第一条规则,因此如果您未指定任何参数,请将流程设为all规则。
  • 不存在名为all的文件,因此需要执行all规则。
  • all取决于dependency1规则。没有名为dependency1的文件,因此需要执行dependency1规则。
  • dependency1取决于dependency2规则。没有名为dependency2的文件,因此需要执行dependency2规则。

您想要的是类似于以下内容:

OBJS := foo.o bar.o Map.o

all: $(OUTPUTPATH)/MainProgram

$(OUTPUTPATH)/MainProgram: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o $(OUTPUTPATH)/MainProgram

%.o: %.cpp
    $(CC) $(CFLAGS) $(CINCLUDE) $< -c $@

.PHONY: all

请注意以下事项:

  • 由于Make对文件进行操作,因此尽可能按文件名列出规则的目标和依赖项。
  • 不是单独列出.cpp文件,而是使用pattern rule来构建每个.o文件。在模式规则中,$<$@ automatic variables分别用于指定第一个先决条件(文件)和目标(文件)。
  • 默认情况下回显其命令,因此无需echo自己。
  • 对于GNU Make,all列为phony target,以防止Make查找名为all的文件。