有人能给我解释一下这个文件吗?

Can someone explain this makefile to me?

本文关键字:一下 文件 解释      更新时间:2023-10-16

我已经随意使用c++几个月了,我甚至不记得我从哪里得到的,或者如果我自己做的(它的实际结构)。我知道我已经添加了一些库和标志):

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)

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

如果要编译类而不是程序,则需要对文件做一些修改。我假设你想要一个目标文件,而不是一个库;图书馆的规则更为复杂。但这应该能解决问题。

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)是否会自动出现在编译或链接命令中。

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

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)

当您键入不带参数的"make"时,它会查找第一个配方,即从第一列开始,后面有一个冒号的配方。那就是all,它告诉它构建TARG。TARG是文件名。Make已经在许多系统上进行了配置,以便知道如何处理.cpp文件,因此在这个Makefile中没有特定的方法来执行该操作。这里没有使用OBJ构造,所以不需要解释;但它的意思是"将SRC中的。cpp替换为。o",所以OBJ将是filename.o.

看起来已经很不错了。您定义了适当的变量,文件简短且可读,您还想要什么?

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

clean:
    rm -f $(TARG) $(OBJ)
clean-all: clean
    rm -f *~
# mark these targets as non-files.
.PHONY: all clean clean-all