我有一个简单的项目,看起来像这样
\n\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1.o\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 one\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1.o\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 file2.o\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .depend\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Makefile\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n \xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1.cpp\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 one\n \xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1.cpp\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 file2.cpp\nRun Code Online (Sandbox Code Playgroud)\n\nMakefile 是这样的:
\n\n# Get all of the source files\nSRC = $(shell find src/ -name "*.cpp")\n# Get all of the object files\nOBJ = $(subst src,build,$(SRC:.cpp=.o))\n\n$(OBJ):\n @mkdir -p $(shell dirname $@)\n g++ -g -c $(subst build,src,$(subst .o,.cpp,$@)) -o $@\n\nall: depend build\n\nbuild: $(OBJ)\n gcc -o project $^\n\ndepend:\n g++ -MM $(SRC) > .depend\n sed -i \'s/.\\/src/.\\/build\\//g\' .depend\n\nsinclude .depend\nRun Code Online (Sandbox Code Playgroud)\n\n我尝试通过运行生成 makefile 依赖项g++ -MM src/file1.cpp src/one/file1.cpp src/one/file2.cpp > .depend,它会生成以下指令:
file1.o: src/file1.cpp <other headers>\nfile1.o: src/one/file1.cpp <other headers>\nfile2.o: src/one/file2.cpp <other headers>\nRun Code Online (Sandbox Code Playgroud)\n\n这样做的问题是build/file1.o不匹配file1.o,因此,更改src/file1.cpp或其依赖的任何标头不会导致目标文件被重建。起初我认为这可能是在生成 .depend 文件之前运行的问题,但即使我随后sinclude .depend运行 .depend 文件,问题仍然存在。从我读到的所有内容来看,没有任何参数或选项可以保留名称的路径。make dependmake buildg++
是否可以通过这种方式生成依赖文件,或者这是构建项目的根本错误方法?
\n\n我查看了这个问题被标记为可能重复的问题的答案,但问题似乎是询问如何为项目创建完整的 makefile,而我的问题不是创建 Makefile,而是而是依赖生成的问题gcc -MM。该问题的答案并不能解决我的问题。
关于什么:
# Get all of the source files
SRC = $(shell find src/ -name "*.cpp")
# Get all of the object files
OBJ = $(patsubst src/%.cpp,build/%.o,$(SRC))
.PHONY: all
all: project
project: $(OBJ)
gcc -o $@ $^
$(OBJ): build/%.o: src/%.cpp
@mkdir -p $(dir $@)
g++ -g -c $< -o $@
.depend: $(SRC)
g++ -MM $^ > $@ && \
sed -Ei 's#^(.*\.o: *)src/(.*/)?(.*\.cpp)#build/\2\1src/\2\3#' $@
include .depend
Run Code Online (Sandbox Code Playgroud)
该sed命令替换任何:
file.o: src/file.cpp ...
Run Code Online (Sandbox Code Playgroud)
经过:
build/file.o: src/file.cpp ...
Run Code Online (Sandbox Code Playgroud)
以及任何:
file.o: src/X/Y/Z/file.cpp ...
Run Code Online (Sandbox Code Playgroud)
经过:
build/X/Y/Z/file.o: src/X/Y/Z/file.cpp ...
Run Code Online (Sandbox Code Playgroud)
目标是直接的.depend,它具有所有源文件作为依赖项,因此如果丢失或比任何源文件更旧,它会自动重建。无需使用depend虚假目标或将其添加为先决条件all(如果需要,make 会自动尝试重建包含的文件include)。
我添加了一些 GNU make 功能(patsubst静态模式规则、自动变量的系统使用...)如果您使用其他 make,请重新处理不支持的功能。