【问题标题】:Any way to use variables as rules and prerequisites in GNU Make?有什么方法可以在 GNU Make 中使用变量作为规则和先决条件?
【发布时间】:2019-11-05 20:54:51
【问题描述】:

我正在尝试设置我的 Makefile,以便我可以在一些变量中定义所有输入和输出,因此我只需要编写一个规则来编译项目。这使我可以最小化 Makefile 代码,并且仍然可以控制我的项目中的内容。这是相关的sn-p代码:


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 $@

除了第二条规则中的$&lt; 部分外,这大部分都有效,它总是使用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

我知道这是因为 $&lt; 采用了第一个依赖项,我认为 make 会足够聪明地解决这个问题,因为 .o 行为是我想要的。

$^ 不是我想要的。我希望 gcc 为每个 cpp 文件创建一个单独的目标文件。

【问题讨论】:

  • 你根本不需要第二条规则。 make 知道如何从 .cpp 创建 .o。
  • “它总是使用 main.cpp”似乎没有错。您可能暗示它从不处理 src1。为何如此?什么输出/行为/症状让你这么认为?请证明您遇到的问题。你做了什么?例如。你触摸了哪个文件?你期待什么?
  • 您是否在寻找插入整个依赖行的$^?
  • @Yunnosch 我编辑了 OP 以进行澄清。
  • @ryan 看看我的做法github.com/igagis/prorab

标签: c++ makefile gnu-make


【解决方案1】:

$&lt; 始终采用 first 先决条件。由于您的规则扩展为

$(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 $@

在这里,$&lt; 做了正确的事情,因为 $(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 的函数调用语法是图灵完备的,因此您可以执行任何需要的计算来得出正确的规则。但是,可读性会受到影响,因此请谨慎使用。

【讨论】:

  • 有什么方法可以对变量使用模式规则吗?只是好奇。
  • 也有可能使用静态模式规则:它基本上是一种模式规则,仅限于给定的一组文件:$(files) : $(pattern) : $(prerequisites) ; $(recipe)。有关详细信息,请参阅gnu.org/software/make/manual/make.html#Static-Pattern。据我记得,这些规则有一些怪癖,使它们难以正确使用,但这并不意味着它们对您的情况没有用处。
  • As far as I remember, those rules have some quirks 不多。基本上,它们被称为“模式规则”,但被视为“显式规则”。所以它们可以被看作是“foreach”的一种简写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多