如何理解这个Makefile?

时间:2011-03-30 21:06:19

标签: makefile

我是“Make”的新手。关于以下Makefile:

CXX ?= g++
CFLAGS = -Wall -Wconversion -O3 -fPIC
SHVER = 2

all: svm-train svm-predict svm-scale

lib: svm.o
  $(CXX) -shared -dynamiclib svm.o -o libsvm.so.$(SHVER)

svm-predict: svm-predict.c svm.o
    $(CXX) $(CFLAGS) svm-predict.c svm.o -o svm-predict -lm
svm-train: svm-train.c svm.o
   $(CXX) $(CFLAGS) svm-train.c svm.o -o svm-train -lm
svm-scale: svm-scale.c
   $(CXX) $(CFLAGS) svm-scale.c -o svm-scale
svm.o: svm.cpp svm.h
   $(CXX) $(CFLAGS) -c svm.cpp
clean:
  rm -f *~ svm.o svm-train svm-predict svm-scale libsvm.so.$(SHVER)

如何理解这个Makefile的流程?例如,“all”和“lib”在这里做什么?如何分析

$(CXX) -shared -dynamiclib svm.o -o libsvm.so.$(SHVER)

4 个答案:

答案 0 :(得分:3)

如果您输入

$ make all

它将构建all :右侧的所有内容,例如svm-train,svm-predict和svm-scale

$(CXX) -shared -dynamiclib svm.o -o libsvm.so.$(SHVER)

是构建目标lib的具体规则,它将转换为

g++ -shared -dynamiclib svm.o -o libsvm.so.2

取决于变量CXX和SHVER的值。

答案 1 :(得分:1)

目标alllib的行称为依赖项

目标all 取决于目标svm-trainsvm-predictsvm-scale

目标lib 取决于 lib.o

跟随所有这些依赖关系,然后决定需要执行哪些构建命令。

如果您输入 make all ,那么make会尝试确保目标svm-trainsvm-predictsvm-scale都是最新的。然后make会递归检查这些目标的依赖关系,直到耗尽所有依赖关系。

答案 2 :(得分:0)

每个make规则都以相同的方式运作。如果任何依赖项(:右侧的值)已过期,则会重建它们,然后运行规则的配方。在这种情况下,all目标没有配方,因此make只检查依赖项(svm-trainsvm-predictsvm-scale)并构建如果他们已经过时了。

lib目标类似 - 如果svm.o已过期,则构建$(CXX) -shared -dynamiclib svm.o -o libsvm.so.$(SHVER) ,然后是食谱

$(CXX)

正在运行。由于这是您要求分析的行,$(SHVER)make$(CXX)变量,它们将按照之前的定义填充。在您的情况下,g++$(SHVER)2g++ -shared -dynamiclib svm.o -o libsvm.so.2 。将要运行的命令是:

$(CXX)

至少假设您没有在其他地方定义?= - 用于进行该分配的make运算符仅在尚未定义变量时才有效。

在命令行中键入make -d时,应该在执行时看到标准输出上的每个命令。您可以使用make -n或{{1}}获取更多调试/日志记录信息。

GNU make manual编写得非常好,是恕我直言网上最好的编程资源之一。

答案 3 :(得分:0)

all触发器解决了所有依赖关系(访问提到的触发器):svm-train svm-predict svm-scale

现在,每个触发器都像脚本一样运行,意思是:编译svm.o,使用CXX中使用标志-shared -dynamiclib声明的编译器,输出名为libsvm.so.$(SHVER)的文件(在您的情况下,$(SHVER)将替换为2