CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
$@和$<到底做什么?
摘自《用GNU Make管理项目》第3版第16页(在GNU自由文档许可下):
Automatic variables are set by make after a rule is matched. They
provide access to elements from the target and prerequisite lists so
you don’t have to explicitly specify any filenames. They are very
useful for avoiding code duplication, but are critical when defining
more general pattern rules.
There are seven “core” automatic variables:
$@: The filename representing the target.
$%: The filename element of an archive member specification.
$<: The filename of the first prerequisite.
$?: The names of all prerequisites that are newer than the target,
separated by spaces.
$^: The filenames of all the prerequisites, separated by spaces. This
list has duplicate filenames removed since for most uses, such as
compiling, copying, etc., duplicates are not wanted.
$+: Similar to $^, this is the names of all the prerequisites separated
by spaces, except that $+ includes duplicates. This variable was
created for specific situations such as arguments to linkers where
duplicate values have meaning.
$*: The stem of the target filename. A stem is typically a filename
without its suffix. Its use outside of pattern rules is
discouraged.
In addition, each of the above variables has two variants for
compatibility with other makes. One variant returns only the directory
portion of the value. This is indicated by appending a “D” to the
symbol, $(@D), $(<D), etc. The other variant returns only the file
portion of the value. This is indicated by appending an “F” to the
symbol, $(@F), $(<F), etc. Note that these variant names are more than
one character long and so must be enclosed in parentheses. GNU make
provides a more readable alternative with the dir and notdir
functions.
$@和$<被称为自动变量。变量$@表示目标的名称,$<表示创建输出文件所需的第一个前提条件。
例如:
hello.o: hello.c hello.h
gcc -c $< -o $@
在这里,你好。O是输出文件。这就是$@展开的结果。第一个依赖项是hello.c。这就是$<展开的内容。
-c标志生成.o文件;有关更详细的解释,请参阅man GCC。-o指定要创建的输出文件。
要了解更多详细信息,可以阅读linoxide上关于Linux Makefiles的文章。
此外,您可以查看GNU make手册。这将使生成makefile和调试它们变得更容易。
如果你运行这个命令,它将输出makefile数据库:
make -p
例如,如果你想编译源代码,但在不同的目录中有对象:
你需要做的是:
gcc -c -o <obj/1.o> <srcs/1.c> <obj/2.o> <srcs/2.c> ...
但对于大多数宏,结果将是所有对象后面跟着所有源,例如:
gcc -c -o <all OBJ path> <all SRC path>
所以这不会编译任何东西^^,你将不能把你的对象文件放在不同的目录:(
解决方案是使用这些特殊的宏
$@ $<
这将为SRC (SRC /file.c)中的每个.c文件生成一个.o文件(obj/file.o)
$(OBJ):$(SRC)
gcc -c -o $@ $< $(HEADERS) $(FLAGS)
意思是:
$@ = $(OBJ)
$< = $(SRC)
而是一行一行,而不是OBJ的所有行后面跟着SRC的所有行