有什么方法可以在 GNU Make 中使用变量作为规则和先决条件?
Any way to use variables as rules and prerequisites in GNU Make?
我正在尝试以这样一种方式设置我的 Makefile,以便我可以在某些变量中定义所有输入和输出,所以我只需要编写一个规则来编译项目。这允许我最小化 Makefile 代码,并且仍然可以控制项目中的内容。这是相关的代码片段:
ROOT_OBJS=
$(B)/main.o
$(B)/src1.o
ROOT_SRC=
$(SRC)/main.cpp
$(SRC)/src1.cpp
$(TARGET) : $(ROOT_OBJS)
$(LD) $(LD_FLAGS) $^ -o $@
$(ROOT_OBJS) : $(ROOT_SRC)
$(CXX) $(CFLAGS) $< -o $@
除了第二条规则中的$<
部分外,这主要有效,它始终使用 main.cpp。有什么解决方法还是我以错误的方式解决这个问题?
编辑:为了澄清,这是我期望的输出:
g++ main.cpp -o main.o
g++ src1.cpp -o src1.o
这是我得到的输出:
g++ main.cpp -o main.o
g++ main.cpp -o src1.o
我知道这是因为$<
需要第一个依赖项,我认为make足够聪明,可以弄清楚,因为.o行为是我想要的。
$^
不是我要找的。我希望 gcc 为每个 cpp 文件创建一个单独的对象文件。
$<
总是需要第一个先决条件。由于您的规则扩展到
$(B)/main.o $(B)/src1.o : $(SRC)/main.cpp $(SRC)/src1.cpp
$(CXX) $(CFLAGS) $< -o $@
$(SRC)/main.cpp
始终是第一个先决条件。就make
而言,$(B)/main.o
和$(SRC)/main.cpp
之间没有神奇的联系。
如果希望规则建立此连接,则必须将其编码到规则中。有几种方法可以做到这一点。最直接的是为每个目标编写单独的规则:
$(B)/main.o : $(SRC)/main.cpp
$(CXX) $(CFLAGS) $< -o $@
$(B)/src1.o : $(SRC)/src1.cpp
$(CXX) $(CFLAGS) $< -o $@
您还可以使用如下所示的模式规则:
$(B)/%.o : $(SRC)/%.cpp
$(CXX) $(CFLAGS) $< -o $@
在这里,$<
做正确的事情,因为$(SRC)/%.cpp
是用模式参数化的,所以它将扩展到正确的源文件。
你拥有的最大枪是生成个人规则:
STEMS := main src1
$(foreach stem,$(STEMS),
$(eval $(B)/$(stem).o: $(SRC)/$(stem).cpp ; $(CXX) $(CFLAGS) $< -o $@))
在这里,我使用$(foreach)
内部函数调用遍历$(STEMS)
中的所有单词,并使用$(eval)
函数调用每次迭代生成一个规则。这是GNU Make语法,只是其他make
实现可能没有这些功能。但是,这是告诉make
该做什么的最通用和最灵活的方法。 GNU Make的函数调用语法是图灵完备的,所以你可以执行任何你需要的计算来提出正确的规则。但是,可读性会受到影响,因此请谨慎使用它。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 有什么方法可以在 GNU Make 中使用变量作为规则和先决条件?
- 类静态变量初始化的规则是什么?
- 如何在包含 typedef 时用从右到左的规则解释变量声明
- Vera TCL规则:列出所有本地变量
- 一个定义规则是否强制创建一个静态函数变量
- 如何理解C++变量作用域规则
- Makefile没有使用我的变量和规则(即编译器和它的标志)
- as-if规则是否防止编译器对全局/成员变量的访问重新排序
- 在不同的翻译单元中的两个变量违反了一个定义规则
- 在c++中返回局部变量(Effective c++第3版规则21)
- GNU Make -在规则/目标中设置shell命令输出中的MAKEFILE变量
- lambda捕获变量的规则
- 根据字符串变量设置的规则进行排序