我是 makefile 的新手,它们让我困惑。我有以下文件夹层次结构:
名为lib
的文件夹包含两个文件夹:include
(包含文件mylib.h
)和src
(与文件mylib.cpp
)。它还包含一个 Makefile,由于某种原因,它给了我一个错误。
完整的 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.so
,g++
必须对 mylib.o
做一些事情。因此,在lib
中,必须出现一个名为mylib.o
的文件。使用通用 %.0
规则,该文件由 src
中的 mylib.cpp
和 mylib.h
组成在 include
中(因此是 %.o
规则的第一行)。该文件是使用 g++
生成的,它必须在 include
中查找其他 header ,生成 mylib.o
作为输出,并编译 src/mylib.cpp
,但 -c
保证生成 .o
文件。
显然,出现了问题,但我无法弄清楚到底是什么问题。就在两天前,我才了解了什么是 Makefile 以及为什么应该学习如何处理它们,所以我并不是那么专家。
最佳答案
您的构建目标 %.o
写错了。您不能使用%
在命令部分,因此目标文件和依赖文件的名称永远不会匹配。
正确的更改是执行以下操作:
%.o: src/%.cpp include/%.h
g++ $(CFLAGS) \
-I include \
-o $@ \
-c src/$(@:%.o=%.cpp)
为了解释这些变化,-o
需要目标文件,它几乎总是写为 $@
在 Makefile 中,因为这是目标的名称。
其次,源文件需要根据目标来定义,所涉及的运算符是模式替换运算符 $(@:%.o=%.cpp)
,所以它所做的就是获取目标 - 它将匹配文件名 <blah>.o
,然后它模式匹配替换 .o
与 .cpp
.
所以在目标 mylib.o
的情况下,变量$@
是 mylib.o
,以及执行 $(@:%.o=%.cpp)
的结果就是转mylib.o
进入mylib.cpp
。因此,正在编译的是预期的文件,并且预期的目标是构建。
使用 %
的规则其中的模式被称为隐式规则,用于降低所编写代码的复杂性 - 如果您有一堆共享目标模式的文件:blah.o: src/blah.cpp src/blah.h
,那么你使用隐式规则只需要编写一次目标,然后你需要根据目标编写命令。
关于c++ - Makefiles : specific 'no input files' , 自动变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35326931/