困惑我的Makefile如何重建目标文件

时间:2015-05-09 17:22:00

标签: c++ makefile

我的make文件在尝试重新创建目标文件时无法找到我的include目录。例如,当我调用make tests时,我得到输出:

g++    -c -o sdl_class.o sdl_class.cpp
sdl_class.cpp:9:23: fatal error: sdl_class.h: No such file or directory
#include <sdl_class.h>
                   ^
compilation terminated.
make: *** [sdl_class.o] Error 1

我的Makefile是这样的:

#Originally from: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
#But will be heavily modified
IDIR =../include
CC=g++
CFLAGS=-w -I$(IDIR)

#ODIR=obj
LDIR =../lib

LIBS=-lSDL2

_DEPS = sdl_class.h SDL_image.h 
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

OBJ = sdl_class.o tests.o 
#OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


%.o: %.cpp $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS) $(LIBS)

tests: sdl_class.o tests.o
    $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

all: $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
    rm -f *.o *~ core $(IDIR)/*~ 

我的理解是,当我调用make tests时,它应该尝试重新制作sdl_class.o文件。然后应该调用%.o规则,该规则应该尝试通过调用以下内容来创建目标文件:

g++ -c -o sdl_class.o sdl_class.cpp -w -I../include -lSDL2

但是,情况并非如此,因为它看起来正在调用$(CC) -c -o $@ $< $(CFLAGS) $(LIBS),正如您从上面可以看到的那样。

我对make如何制定规则有一个根本的误解吗?似乎很可能,这是我的第一个Makefile。也许我对汇编的工作原理感到困惑,因为我对此也有点新意。

2 个答案:

答案 0 :(得分:1)

我想问的是,../include/sdl_class.h../include/SDL_image.h中的一个或多个文件不存在。因此,make决定您的模式规则不匹配(因为不能找到或创建所有先决条件),并且默认使用内置规则从.cpp文件创建目标文件。

内置规则对C ++编译器使用make变量CXX,对C ++标志使用CXXFLAGSCCCFLAGS变量用于C编译器。这就是为什么CFLAGS的设置被忽略的原因。

如果您运行make -d sdl_class.o,您将会看到make正在查找哪个文件以及为什么它决定不使用您的模式规则。

如果您重写这样的规则,它会更好用:

%.o: %.cpp
        $(CC) -c -o $@ $< $(CFLAGS)

sdl_class.o tests.o: $(DEPS)

因为make现在会抱怨无法找到或创建相关文件。

当然还有其他问题。你不应该将$(LIBS)传递给你的编译命令;仅属于您的链接行。并且,你应该坚持使用C ++编译器的标准变量CXXCPPFLAGS用于预处理器标志,如-I-D,以及CXXFLAGS用于C ++编译器标志。此外,-L../lib等链接器库标志位于LDFLAGS-lSDL2等链接器库位于LDLIBS

答案 1 :(得分:0)

CC / CCFLAGS用于C编译。您应该使用CXX和CXXFLAGS for C ++。它们用于内置规则和LINK.cc宏中,使Makefile更简单,因此更不容易出错。

CXXFLAGS = -Wall ...
prog :  foo.o bar.o
      $(LINK.cc) -o $@ $^

请参阅Default linker setting in Makefile for linking C++ object files