帮助简化多个可执行文件的 Makefile
我有多个可执行文件使用的通用代码(例如 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
I have common code (e.g. hello.cpp
) that is used by multiple executables. I'm using a single Makefile to build it all:
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++ lt; $(OBJ) -o $@
app2.out: app2.o $(OBJ)
g++ lt; $(OBJ) -o $@
.cpp.o:
g++ -c lt; -o $@
clean:
rm -f $(EXE) $(OBJ) $(OBJ_MAIN)
I'm not very happy about having a separate target for each executable -- the targets are essentially the same. Is there any way to do this with one target for all executables? I was hoping that something like this would work:
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++ lt; $(OBJ) -o $@
.cpp.o:
g++ -c lt; -o $@
clean:
rm -f $(EXE) $(OBJ) $(OBJ_MAIN)
But I get a linking error:
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
For some reason it tries to build app1.out
without building its dependency hello.o
. Can anyone explain why this doesn't work, and suggest something that does?
Here's the rest of the dummy code, just in case.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题似乎是您正在使用旧式后缀规则。从制作信息来看:
解决方案是使用新式模式规则:(
另请注意,您不需要定义 .cpp 到 .o 规则;
make
有一个合理的默认值。)The problem appears to be that you are using old-style suffix rules. From the make info:
The solution is to use new-style pattern rules:
(Also note that you don't need to define a .cpp to .o rule;
make
has a sensible default.)