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

时间:2023-01-13 09:58:52

My make file is failing to find my include directory when it tries to remake object files. For example, when I call make tests I get the output:

我的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

My Makefile is this:

我的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)/*~ 

My understanding is that when I call make tests, that it should attempt to remake the sdl_class.o file. This should then call the %.o rule, which should try to make the object file by calling something like:

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

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

However, this is not the case as it looks like it is calling $(CC) -c -o $@ $< $(CFLAGS) $(LIBS), as you can see from above.

但是,情况并非如此,因为它看起来像是在调用$(CC)-c -o $ @ $ <$(CFLAGS)$(LIBS),如上所示。

Do I have a fundamental misunderstanding about how make builds its rules? Seems likely, this is my first Makefile. Perhaps I am confused on how compilation works in general, as I'm somewhat new to that as well.

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

2 个解决方案

#1


I would say that the problem is that one or more of the files ../include/sdl_class.h or ../include/SDL_image.h does not exist. Because of that, make is deciding that your pattern rule does not match (because not all the prerequisites can be found or made) and it defaults to the built-in rule to create object files from .cpp files.

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

The built-in rules use the make variables CXX for the C++ compiler and CXXFLAGS for the C++ flags: the CC and CFLAGS variables are used for the C compiler. That's why your settings for CFLAGS are being ignored.

内置规则使用C ++编译器的make变量CXX和C ++标志的CXXFLAGS:CC和CFLAGS变量用于C编译器。这就是为什么你的CFLAGS设置被忽略了。

If you run make -d sdl_class.o you'll see which file make is looking for and why it decides to not use your pattern rule.

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

If you rewrite your rules like this it will work better:

如果你像这样重写你的规则它会更好:

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

sdl_class.o tests.o: $(DEPS)

because make will now complain that the relevant files can't be found or created.

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

There are other issues, of course. You shouldn't be passing $(LIBS) to your compile command; that belongs only in your link line. And, you should probably stick to the standard variables CXX for the C++ compiler, CPPFLAGS for preprocessor flags like -I and -D, and CXXFLAGS for C++ compiler flags. Also, linker library flags like -L../lib go in LDFLAGS and linker libraries like -lSDL2 go in LDLIBS.

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

#2


CC/CCFLAGS are for C compilation. You should use CXX and CXXFLAGS for C++. They are used in built-in rules and in the LINK.cc macro, making the Makefile much simpler, and thus less error prone.

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

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

see Default linker setting in Makefile for linking C++ object files

请参阅Makefile中用于链接C ++目标文件的默认链接器设置

#1


I would say that the problem is that one or more of the files ../include/sdl_class.h or ../include/SDL_image.h does not exist. Because of that, make is deciding that your pattern rule does not match (because not all the prerequisites can be found or made) and it defaults to the built-in rule to create object files from .cpp files.

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

The built-in rules use the make variables CXX for the C++ compiler and CXXFLAGS for the C++ flags: the CC and CFLAGS variables are used for the C compiler. That's why your settings for CFLAGS are being ignored.

内置规则使用C ++编译器的make变量CXX和C ++标志的CXXFLAGS:CC和CFLAGS变量用于C编译器。这就是为什么你的CFLAGS设置被忽略了。

If you run make -d sdl_class.o you'll see which file make is looking for and why it decides to not use your pattern rule.

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

If you rewrite your rules like this it will work better:

如果你像这样重写你的规则它会更好:

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

sdl_class.o tests.o: $(DEPS)

because make will now complain that the relevant files can't be found or created.

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

There are other issues, of course. You shouldn't be passing $(LIBS) to your compile command; that belongs only in your link line. And, you should probably stick to the standard variables CXX for the C++ compiler, CPPFLAGS for preprocessor flags like -I and -D, and CXXFLAGS for C++ compiler flags. Also, linker library flags like -L../lib go in LDFLAGS and linker libraries like -lSDL2 go in LDLIBS.

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

#2


CC/CCFLAGS are for C compilation. You should use CXX and CXXFLAGS for C++. They are used in built-in rules and in the LINK.cc macro, making the Makefile much simpler, and thus less error prone.

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

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

see Default linker setting in Makefile for linking C++ object files

请参阅Makefile中用于链接C ++目标文件的默认链接器设置