我正在尝试为我的C ++程序编写一个生成自动执行的makefile。我回顾了this tutorial,并一直在审查GNU制作手册。似乎make正在生成我的.d文件,但没有读取它们,或者它读取它们但由于某种原因不能使用它们。
我的项目包含以下目录:
这是我的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 $@; \
$(GPP) -I$(INC) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,$(OBJ)/\1.o : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
.PHONY:clean
clean:
rm -f $(OBJ)/*.o
rm -f $(DEP)/*.d
rm -f $(BIN)/*
当我运行make时,它会生成&#39; makedeps&#39;下的所有依赖项文件。目录,这是它们的连接输出:
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 make manual文档中找到了这个:
编译C ++程序:
n.o
是从n.cc
,n.cpp
或n.C
自动生成的,其形式为“$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
”
这就是我在上面设置CXX = $(GPP)的原因。
但是,没有生成目标文件。这是make输出:
mike@ubuntu:~/NetBeansProjects/CppApplication_1$ make -f mk.mk clean
rm -f objects/*.o
rm -f makedeps/*.d
rm -f bin/*
mike@ubuntu:~/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文件首先被删除,我确认它们是在make运行时创建的。仔细阅读this section on include directives之后,我的印象是make应该(再次)尝试在创建这些.d文件后加入这些文件。
有人请解释为什么没有生成目标文件吗?
答案 0 :(得分:2)
如果您的目标由于隐式规则查找的工作方式而具有路径分隔符,则您无法依赖隐式规则,解决问题的最直接方法是在$(BIN)/app.exe
之后提供明确的方法
$(objects):
$(GPP) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $@
尽管如此,GCC已经有一段时间了更好的依赖生成,但看起来文档还没有赶上。您可以使用-MMD
生成依赖关系作为编译的副作用,这意味着您可以摆脱所有sed
crud(-MP
添加标头的虚拟目标,以避免在删除它们时出现问题)。
你的Makefile看起来像这样
BIN := bin
SRC := src
INC := include
OBJ := objects
app := $(BIN)/app.exe
sources := $(wildcard $(SRC)/*.cpp)
objects := $(subst $(SRC),$(OBJ),$(sources:.cpp=.o))
deps := $(objects:.o=.d)
CXX := g++
CPPFLAGS := -I $(INC) -MMD -MP
CXXFLAGS := -std=c++11
LDFLAGS := -L /usr/lib/x86_64-linux-gnu
LDLIBS := -lcurl
$(app) : $(objects)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(OBJ)/%.o: $(SRC)/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $@
.PHONY: clean
clean: ; $(RM) $(objects) $(deps) $(app)
-include $(deps)
您可以从文件中看到的其他一些注释
:=
代替=
-MF
更改输出文件。CPPFLAGS
,它不会执行任何预处理。CXX
就此而言)。$@
等)。如果你真的想使用隐式规则,你需要做一些事情,比如从目标文件中剥离路径并事先更改为对象目录。