生成文件:特定的"无输入文件",自动变量

Makefiles: specific 'no input files', automatic variables

本文关键字:文件 输入 变量      更新时间:2023-10-16

我是制作文件的新手,他们让我感到困惑。我有以下文件夹层次结构:

名为 lib 的文件夹包含拖曳文件夹:include(带有文件 mylib.h (和src(带有文件 mylib.cpp (。它还包含一个 Makefile,由于某种原因,它给了我一个错误。

完整的生成文件是:

CFLAGS = -Wall -fPIC
OBJECTS = mylib.o
all: libmine.so
libmine.so: $(OBJECTS)
            g++ -shared $(CFLAGS) 
            -o libmine.so 
            $(OBJECTS)
%.o:        src/%.cpp include/%.h
            g++ $(CFLAGS) 
            -I include 
            -o %.o 
            -c src/%.cpp
clean:
            rm src/*.o
            rm libmine.so

错误是

mr209@Quantum:~/Desktop/hw1/lib$ make
g++ -Wall -fPIC 
            -I include 
            -o %.o 
            -c src/%.cpp
g++: error: src/%.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [mylib.o] Error 4

但该文件存在。因此,make正在做奇怪的事情,导致它无法找到.cpp文件。

为了libmine.sog++必须对mylib.o做一些事情,对于一个通用的.o文件,我已经写了几行代码。

这就是我在想的:为了libmine.sog++将不得不对mylib.o做点什么。因此,在lib中,必须出现一个名为mylib.o的文件。使用通用%.0规则,此文件由 src 中的mylib.cppinclude 中的mylib.h创建(因此是%.o规则的第一行(。该文件是使用 g++ 制作的,它必须在include中查找其他标头,生成mylib.o作为输出,并编译src/mylib.cpp,但-c保证生成.o文件。

显然,出了点问题,我无法弄清楚是什么。直到 2 天前,我才知道什么是 Makefiles 以及为什么应该学习如何处理它们,所以我不是那么多专家。

您的构建目标%.o写错了。不能使用命令部分中的%,因此目标文件和依赖文件的名称将永远不匹配。

正确的更改是执行以下操作:

%.o: src/%.cpp include/%.h
    g++ $(CFLAGS) 
    -I include 
    -o $@ 
    -c src/$(@:%.o=%.cpp)

只是为了解释这些更改,-o需要目标文件,该文件几乎总是以$@的形式写入 Makefiles,因为这是目标的名称。

其次,源文件需要根据目标进行定义,所讨论的运算符是模式替换运算符$(@:%.o=%.cpp),因此它所做的是获取目标 - 这将匹配<blah>.o文件名,然后它模式匹配将.o替换为.cpp

所以在目标mylib.o的情况下,变量$@mylib.o的,做$(@:%.o=%.cpp)的结果是把mylib.o变成mylib.cpp。因此,正在编译的是预期的文件,并且正在生成预期的目标。

在其中使用 % 模式的规则被称为隐式规则,

用于降低正在编写的代码的复杂性 - 如果您有一堆共享目标模式的文件:blah.o: src/blah.cpp src/blah.h ,那么您使用隐式规则只需要编写目标一次, 然后,您需要根据目标编写命令。

在将变量放入 g++ 之前,必须先做一个变量喜欢:

FT_C= $(src/%.cpp) FT_O=$(FT_C:.c=.o)

g++ $(CFLAGS) -I include -o $(FT_O) -c $(FT_C)

并且不要把你的.h放在编译中 '-I' 就是为了它。

如果你想理解我的意思,看看这个例子:

https://github.com/emericspiroux/wolf3d/blob/master/libft/Makefile