我有多个可执行文件使用的公共代码(例如hello.cpp
)。我正在使用单个Makefile来构建它:
EXE=app1.out app2.out
SRC=hello.cpp
OBJ=$(SRC:.cpp=.o)
SRC_MAIN=app1.cpp app2.cpp
OBJ_MAIN=$(SRC_MAIN:.cpp=.o)
all: $(EXE)
app1.out: app1.o $(OBJ)
g++ $< $(OBJ) -o $@
app2.out: app2.o $(OBJ)
g++ $< $(OBJ) -o $@
.cpp.o:
g++ -c $< -o $@
clean:
rm -f $(EXE) $(OBJ) $(OBJ_MAIN)
我对每个可执行文件都有一个单独的目标感到不满 - 目标基本相同。对于所有可执行文件,是否有任何方法可以使用一个目标?我希望像这样的东西能起作用:
EXE=app1.out app2.out
SRC=hello.cpp
OBJ=$(SRC:.cpp=.o)
SRC_MAIN=app1.cpp app2.cpp
OBJ_MAIN=$(SRC_MAIN:.cpp=.o)
all: $(EXE)
.o.out: $(OBJ)
g++ $< $(OBJ) -o $@
.cpp.o:
g++ -c $< -o $@
clean:
rm -f $(EXE) $(OBJ) $(OBJ_MAIN)
但是我收到了链接错误:
misha@misha-desktop:~/cpp/stack$ make -f Makefile2
g++ -c app1.cpp -o app1.o
g++ app1.o hello.o -o app1.out
g++: hello.o: No such file or directory
make: *** [app1.out] Error 1
rm app1.o
由于某种原因,它尝试构建app1.out
而不构建其依赖项hello.o
。任何人都可以解释为什么这不起作用,并提出一些建议吗?
以下是其余的虚拟代码,以防万一。
app1.cpp:
#include "hello.h"
int
main(void)
{
print_hello();
}
app2.cpp:
#include "hello.h"
int
main(void)
{
for (int i = 0; i < 4; ++i)
print_hello();
return 0;
}
HELLO.CPP:
#include "hello.h"
#include <stdio.h>
void
print_hello()
{
printf("hello world!\n");
}
hello.h:
#ifndef HELLO_H
#define HELLO_H
void
print_hello();
#endif
答案 0 :(得分:4)
问题似乎是您使用的是旧式后缀规则。来自make info:
后缀规则不能有自己的任何先决条件。如果他们 有任何,他们被视为有趣名字的普通文件,而不是 后缀规则。因此,规则:
.c.o: foo.h $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
讲述了如何从必备文件'foo.h'创建文件'.c.o', 并且完全不像模式规则:
%.o: %.c foo.h $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
讲述如何从'.c'文件制作'.o'文件,并使所有'.o' 使用此模式规则的文件也依赖于'foo.h'。
解决方案是使用新式模式规则:
%.out: %.o $(OBJ)
g++ $< $(OBJ) -o $@
%.o: %.cpp
g++ -c $< -o $@
(另请注意,您无需将.cpp定义为.o规则; make
具有合理的默认值。)