我是makefiles的新手,他们让我很困惑。我有以下文件夹层次结构:
名为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
规则,此文件来自mylib.cpp
中的src
和mylib.h
中的include
(因此%.o
的第一行规则)。该文件是使用g++
生成的,必须在include
中查找其他标头,生成mylib.o
作为输出,并编译src/mylib.cpp
,但-c
保证生成.o
文件。
显然,出了点问题,我无法弄清楚是什么。仅仅两天前,我才知道Makefile是什么以及为什么要学会如何处理它们,所以我不是那么专家。
答案 0 :(得分:2)
您的构建目标%.o
被误写了。您无法在命令部分中使用%
,因此目标文件和相关文件的名称将无法匹配。
正确的改变是执行以下操作:
%.o: src/%.cpp include/%.h
g++ $(CFLAGS) \
-I include \
-o $@ \
-c src/$(@:%.o=%.cpp)
为了解释这些更改,-o
需要目标文件,它几乎总是在Makefile中写为$@
,因为它是目标的名称。
其次,源文件需要根据目标来定义,所讨论的运算符是模式替换运算符$(@:%.o=%.cpp)
,所以它的作用是取目标 - 它将匹配文件名{{ 1}},然后模式匹配将<blah>.o
替换为.o
。
因此,对于目标.cpp
,变量mylib.o
为$@
,执行mylib.o
的结果是将$(@:%.o=%.cpp)
变为{ {1}}。因此,它是正在编译的预期文件,预期目标是构建。
在其中使用mylib.o
模式的规则被称为隐式规则,用于降低所编写代码的复杂性 - 如果您有一堆共享目标模式的文件:{ {1}},然后你使用隐式规则只需要编写一次目标,然后你需要根据目标编写命令。
答案 1 :(得分:0)
在将它放入g ++之前,你必须先做一个变量 喜欢:
FT_C= $(src/%.cpp)
FT_O=$(FT_C:.c=.o)
和
g++ $(CFLAGS) -I include -o $(FT_O) -c $(FT_C)
并且不要将你的.h编入汇编中。-I&#39;在这里。
如果你想了解我的意思,请看这个例子:
https://github.com/emericspiroux/wolf3d/blob/master/libft/Makefile