【问题标题】:Make: variable requirements that depend on the targetMake:取决于目标的可变需求
【发布时间】:2018-11-18 12:00:17
【问题描述】:

Make:取决于目标的可变需求

我有一个Makefile,大致如下:

default: en

.PHONY: default en es

en: NUMBER=number
es: NUMBER=numero

TARGET=$(NUMBER)-word
INTERMEDIATE=$(NUMBER)-tmp

en: number
es: number

number: $(INTERMEDIATE)
  touch $(TARGET)

$(INTERMEDIATE):
  @echo Please provide file $(INTERMEDIATE)
  @exit 1

clean:
  rm *-word *-tmp

要使用它,您可以调用make en(也是默认设置)或make es。在我看来,这个 Makefile 有两个主要特点:

  • 用户必须提前提供中间要求 ($(INTERMEDIATE))。
  • 此要求是一个变量,其值取决于目标。

当我运行它时,我得到以下信息:

$ make
Please provide file number-tmp
make: *** [-tmp] Error 1

此错误向我表明,对于我的意图而言,变量的解决阶段为时已晚。失败的规则是-tmp,这意味着它在决定运行什么规则时无法告诉$(NUMBER) 的值。但是,它在运行规则时已解决。

那么我怎样才能做到这一点呢?

【问题讨论】:

  • 您的问题不清楚。您希望用户如何在enes 之间进行选择?如果en是默认的,想要es的用户是否应该运行“make es”?
  • 抱歉,您是对的。我已在问题中添加了使用说明。

标签: makefile


【解决方案1】:

The documentation 很清楚,您不能在目标或先决条件中使用特定于目标的变量值:

另一个例外是特定于目标的变量值。此功能允许您根据 make 当前正在构建的目标为同一变量定义不同的值。 与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中)。

您可以通过多种方式处理此问题。最简单的方法是将选择更改为使用变量而不是目标,并使用constructed macro names。假设您将值存储在 LV 变量中(您不应该使用 LANG 等,因为这对 shell 来说是特殊的),如下所示:

# Must be set on the command line
LV =

en_NUMBER := number
es_NUMBER := numero

TARGET := $($(LV)_NUMBER)-word
INTERMEDIATE := $($(LV)_NUMBER)-tmp

ifeq ($(TARGET),-word)
  $(error Missing/invalid LV value: '$(LV)')
endif

number: $(INTERMEDIATE)
        touch $(TARGET)

clean:
        rm *-word *-tmp

如果你运行make LV=en,你会得到number-word。如果你运行make LV=es,你会得到numero-word。如果你运行make(无设置)或make LV=foo(无效设置)你会得到一个错误。

还有其他方法可以做到这一点,但没有完全了解您想要什么,我们无法确定。

【讨论】:

  • 谢谢,您的回答涵盖了我的情况。我意识到我将语言用作变量可能会使事情变得混乱:看起来我想做一些依赖于语言环境的事情(不是这样,这只是一个例子)。
猜你喜欢
  • 2012-12-13
  • 2012-10-03
  • 2011-05-25
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多