我一直在使用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)
我想用它来编译一个类,但首先我必须了解发生了什么,因为我必须稍微修改一下。还有,有什么不好的做法吗?
答案 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