我想为我的C++程序编写一个生成文件,它将生成自动更新。我回顾了this tutorial并且也一直在审查GNU make手册。看起来make是生成我的.d文件但不读取它们,或者它读取它们,但由于某些原因不会使用它们。自动生成自动生成的.d文件,但不读取它们
我的项目是摆好了这些目录:
- Src在.cpp文件
- 包括.HPP文件
- makedeps的.d文件
- 对象为.o文件
- bin为最终的可执行文件
这是我的makefile:
BIN=bin
SRC=src
INC=include
DEP=makedeps
OBJ=objects
# sources are like 'src/main.cpp'
sources=$(wildcard $(SRC)/*.cpp)
# objects are like 'objects/main.o'
objects=$(subst $(SRC),$(OBJ),$(sources:.cpp=.o))
# dependencies are like 'makedeps/main.d'
deps=$(subst $(SRC),$(DEP),$(sources:.cpp=.d))
GPP=g++
CPPFLAGS=-std=c++11
LINKARGS=-L/usr/lib/x86_64-linux-gnu
# used by the implicit rules that the dependency files use:
CXX=$(GPP)
$(BIN)/app.exe : $(objects)
$(GPP) $(CPPFLAGS) $(LINKARGS) $(objects) -lcurl -o $(BIN)/app.exe
# on the first pass this should fail, but it should discover how
# to build these dependencies and then build them and load them in.
# once they are loaded in, it should know how to build the object files.
-include $(deps)
# this produces the dependency files, the sed command puts directory prefixes
# before the files
$(DEP)/%.d : $(SRC)/%.cpp
@set -e; rm -f [email protected]; \
$(GPP) -I$(INC) -MM $(CPPFLAGS) $< > [email protected]$$$$; \
sed 's,\($*\)\.o[ :]*,$(OBJ)/\1.o : ,g' < [email protected]$$$$ > [email protected]; \
rm -f [email protected]$$$$
.PHONY:clean
clean:
rm -f $(OBJ)/*.o
rm -f $(DEP)/*.d
rm -f $(BIN)/*
当我运行make时,它产生的所有相关文件的“makedeps”目录下,这里是他们的级联输出:
objects/DownloadBuffer.o : src/DownloadBuffer.cpp include/DownloadBuffer.hpp
objects/Downloader.o : src/Downloader.cpp include/Downloader.hpp \
include/DownloadBuffer.hpp
objects/main.o : src/main.cpp include/Downloader.hpp
我发现这在GNU就隐含规则手册文档:
编译的C++程序:
n.o
自动从n.cc
,n.cpp
,或n.C
与窗体'的配方制成$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
'
这就是为什么我在上面设置CXX = $(GPP)的原因。
但是,没有生成目标文件。这里是make输出:
[email protected]:~/NetBeansProjects/CppApplication_1$ make -f mk.mk clean
rm -f objects/*.o
rm -f makedeps/*.d
rm -f bin/*
[email protected]:~/NetBeansProjects/CppApplication_1$ make -f mk.mk
g++ -std=c++11 -L/usr/lib/x86_64-linux-gnu objects/DownloadBuffer.o objects/Downloader.o objects/main.o -lcurl -o bin/app.exe
g++: error: objects/DownloadBuffer.o: No such file or directory
g++: error: objects/Downloader.o: No such file or directory
g++: error: objects/main.o: No such file or directory
make: *** [bin/app.exe] Error 1
请注意,.d文件被首先删除,并且我确认它们是在运行时创建的。在仔细阅读this section on include directives之后,我有这样的印象:make应该再次尝试在创建完成后包含这些.d文件。
有人请解释为什么不生成目标文件?
我很困惑,你说我应该有一个明确的配方来创建我的目标文件,但是.d文件应该创建这个配方,冗余规则不会相互冲突吗?我也从来不知道CPPFLAGS只是用于预处理(我认为你的意思是编译对不对?)。我用它来保存-std = C++ 11,从你的解决方案来看,我猜连接器不需要知道标准。 – msknapp 2014-09-23 00:59:56
所以我认为make会为同一个目标合并单独的规则,我是否正确解释? – msknapp 2014-09-23 01:08:55
OMG它的工作!我不必改变一件事!我认为这是我见过的最美丽的制作文件,非常感谢。 – msknapp 2014-09-23 01:24:23