2

我是makefile的新手,他们让我很困惑。我有以下文件夹层次结构:

一个名为的文件夹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.so,g++将不得不做一些事情mylib.o, 对于一个通用.o文件我已经写了一些代码行。

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

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

4

2 回答 2

2

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

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

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

只是为了解释更改,-o需要目标文件,它几乎总是像$@在 Makefiles 中那样编写,因为那是目标的名称。

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

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

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

于 2016-02-10T22:31:45.353 回答
0

在将其放入 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

于 2016-02-10T22:18:18.487 回答