有人可以向我解释这个makefile吗?

时间:2011-07-10 06:37:57

标签: c++ makefile

我一直在使用c ++随便使用makefile几个月我甚至不记得我得到了什么,或者我自己做了什么(它的实际结构。我知道我添加了一些库和标志虽然):

SRC = filename.cpp
TARG = filename

CC = g++

CPPFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 -Wno-unused-function `pkg-config --cflags opencv`

LDFLAGS = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem

OBJ = $(SRC:.cpp=.o)

all: $(TARG)

clean:
    rm -f *~ *.o $(TARG)

我想用它来编译一个类,但首先我必须了解发生了什么,因为我必须稍微修改一下。还有,有什么不好的做法吗?

3 个答案:

答案 0 :(得分:2)

如果你想编译一个类而不是一个程序,你需要对该文件进行一些小的手术。我假设你想要一个目标文件,而不是一个库;图书馆的规则更复杂。但这应该可以解决问题。

SRC = class.cpp
OBJ = $(SRC:.cpp=.o)   
CC  = g++
CPPFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 \
           -Wno-unused-function `pkg-config --cflags opencv`
LDFLAGS = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem
DEBRIS  = core a.out *~

all: $(OBJ)

class.o: class.h

clean:
    rm -f $(DEBRIS) $(OBJ)

目前还不清楚$(CPPFLAGS)是否会自动出现在编译或链接命令中。

如果你最终想要从两个文件构建程序,那么你使用混合:

SRC      = filename.cpp class.cpp
OBJ      = $(SRC:.cpp=.o)
PROGRAM  = program
CXX      = g++
CXXFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 \
           -Wno-unused-function `pkg-config --cflags opencv`
LDFLAGS  = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem
DEBRIS   = core a.out *~

all: $(PROGRAM)

$(PROGRAM): $(OBJ)
    $(CXX) $(CXXFLAGS) -o $@ $(OBJ) $(LDFLAGS)

class.o: class.h
filename.cpp: class.h

clean:
    rm -f $(DEBRIS) $(OBJ) $(PROGRAM)

请注意,我已将C ++编译器的宏从CC更改为CXX。标准对于C ++编译器的名称并不清楚。 POSIX在make的描述中没有提到C ++。但是,CC显然是用于编译C而不是C ++。这不需要阻止你的make版本使用CC进行C ++编译,但这有点不寻常。 (MacOS X 10.6.8上的GNU Make 3.81使用CXX进行C ++编译。)链接行现在使用$(CXXFLAGS)(感谢eriktous);目前尚不清楚对象文件编译的C ++源是否会这样做。最终,这就是为什么你最终会看到带有以下规则的makefile:

class.o: class.h
    $(CXX) -c $(CXXFLAGS) $*.cpp

这可以保证编译规则就是您对此目标文件的看法。您可以将其写为旧式但可移植的后缀规则(.cpp.o:); make的POSIX规范支持这些。或者您可以使用更现代但不一定非常便携的%.o : %.o符号(POSIX不要求)。这些中的任何一个都取代了如何从C ++源代码编译目标文件的任何先前(内置)定义。

.cpp.o:
    $(CXX) -c $(CXXFLAGS) $*.cpp

%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $*.cpp

我假设你正在使用opencv(和一些Boost);如果没有,您的编译和链接标志包括不相关的选项。猜测依赖关系; make将推断目标文件对C ++源代码的依赖性,因此我只列出了头依赖项。但如果您使用opencv和Boost,则可能还有更多。

(Makefiles未经过正式测试。)

答案 1 :(得分:1)

当你输入没有args的“make”时,它会查找第一个配方,从第一个列开始,后面带冒号。那将是all,它告诉它构建TARG。 TARG是文件名。已在许多系统上配置Make以了解如何处理.cpp文件,因此此Makefile中没有特定的配方来执行此操作。这里没有使用OBJ结构,因此无需解释;但这意味着“用.o替换SRC中的.cpp”,所以OBJ就是filename.o。

答案 2 :(得分:1)

它已经看起来不错了。你定义了合适的变量,文件简短易读,你还想要什么?

clean目标中,您只能删除$(OBJ)而不是*.o。并且您不应该在构建过程中删除编辑器的备份文件。我建议这样做:

clean:
    rm -f $(TARG) $(OBJ)

clean-all: clean
    rm -f *~

# mark these targets as non-files.
.PHONY: all clean clean-all