Makefile一次又一次地为不同的对象选择相同的源文件
makefile picks the same source file again and again for different objects
我想写一个makefile,假设我在目录src/app/
中有4个源文件:
src/app/file1.cpp
src/app/file2.cpp
src/app/file3.cpp
src/app/file4.cpp
和我想创建不同的目标文件(即file1.o
, file2.o
等)到另一个名为obj/
的目录。在makefile中,我像这样定义变量:
$(SRC) := $(wildcard src/app/*.cpp)
$(OBJ) := $(addprefix obj/,$(notdir $(SRC:.cpp=.o)))
和我的命令是这样的:
all: $(OBJ)
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c $< -o $@
所以当我运行make
时,我看到这些操作:
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file1.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file2.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file3.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file4.o
您可以看到,目标文件有不同的名称,但源文件是相同的。如何解决?
请注意,我不能使用%.o: %.cpp
,因为我在我的makefile中有其他目标用于不同的目的。
如果你不能使用
obj/%.o: src/app/%.cpp
那么第二种最简单的方法是在前面添加$(OBJ):
:
$(OBJ): obj/%.o: src/app/%.cpp
它被称为"静态模式规则"-在GNU Make手册中查找它。
我已经找到了解决这个问题的方法(感谢Zereges的想法):
$(RGAOBJ): $(RGASRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c
$(addprefix src/app/,$(notdir $(@:.o=.cpp))) -o $@
我认为有更好的方法。
所以其他的指针都是有用的
$<
变量选择第一个依赖项。它用于具有可变靶标的通用靶标,并产生不同的结果。编译目标将匹配模式作为目标,并具有通用依赖项。在您的例子中,第一个目标不会改变。
不能使用通用规则的约束完全违背了$<
变量的目的。一种比较天真的解决方法是将目标名称转换回源名称,例如
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c $(@:%.o=%.cpp) -o $@
这种方法的问题是并不是所有的目标文件都依赖于所有的源文件。因此,每当一个源文件被更改时,就会生成所有的目标文件。对于可能可行的小项目和资源。对于任何我认为是实的投影,这两个条件都不成立。
我对你说不能使用模式规则的理解是,你已经有了相同模式的规则,但你需要用一些特殊的规则来建立一些目标。针对这种情况的一种解决方案是使用自定义后缀构建目标,该后缀实际上构建的是不同的东西,并且只是使用标记文件来防止不必要的重建。例如:
all: $(OBJ:%=%.custom)
%.o.custom: %.cpp
$(CC) $(CFLAGS) -W -I/src/app/app.h -c $< -o $(@:%.custom=%) && touch $@
相关文章:
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- QTreeView幻灯片多选后无法使用单击选择
- 无法获取菜单选择以运行函数.C++
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 为测试目标创建具有不同源文件夹的文件
- 在C++中,如何通过几种类型从元组中选择多个元素
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 将图像添加到资源文件夹UWP C++
- 对可变参数使用声明.如何选择正确的功能
- 选择选举获胜者的程序
- 视觉工作室项目.提取源文件夹名称
- 如何选择在 csv 文件中输出的位置
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- CMake:如何为每个源文件选择传递哪些包含目录
- 我如何选择每个平台收集哪些源文件
- 选择在构建/调试时首先显示源文件(.cpp)
- Makefile一次又一次地为不同的对象选择相同的源文件