帮助简化多个可执行文件的Makefile

mpe*_*kov 8 c++ 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)
Run Code Online (Sandbox Code Playgroud)

对于每个可执行文件都有一个单独的目标我感到不高兴 - 目标基本相同.对于所有可执行文件,是否有任何方法可以使用一个目标?我希望这样的东西能起作用:

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)
Run Code Online (Sandbox Code Playgroud)

但我收到一个链接错误:

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
Run Code Online (Sandbox Code Playgroud)

出于某种原因,它试图在app1.out不构建依赖性的情况下构建hello.o.任何人都可以解释为什么这不起作用,并提出一些建议吗?

这是其余的虚拟代码,以防万一.

app1.cpp:

#include "hello.h"   
int
main(void)
{
    print_hello();
}
Run Code Online (Sandbox Code Playgroud)

app2.cpp:

#include "hello.h"    
int
main(void)
{
    for (int i = 0; i < 4; ++i)
        print_hello();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

HELLO.CPP:

#include "hello.h"    
#include <stdio.h>    
void
print_hello()
{
    printf("hello world!\n");
}
Run Code Online (Sandbox Code Playgroud)

hello.h:

#ifndef HELLO_H
#define HELLO_H
void
print_hello();
#endif
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 4

问题似乎是您正在使用旧式后缀规则。从制作信息来看:

后缀规则不能有任何自己的先决条件。如果有的话,它们会被视为具有有趣名称的普通文件,而不是后缀规则。因此,规则:

  .c.o: foo.h
          $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

告诉如何从先决条件文件“foo.h”创建文件“.co”,并且与模式规则完全不同:

  %.o: %.c foo.h
          $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

它告诉我们如何从“.c”文件创建“.o”文件,并使所有使用此模式规则的“.o”文件也依赖于“foo.h”。

解决方案是使用新型模式规则:

%.out: %.o $(OBJ)
    g++ $< $(OBJ) -o $@
%.o: %.cpp
    g++ -c $< -o $@
Run Code Online (Sandbox Code Playgroud)

(另请注意,您不需要定义 .cpp 到 .o 规则;make有一个合理的默认值。)