代码之家  ›  专栏  ›  技术社区  ›  pablobm

制造:取决于目标的可变需求

  •  0
  • pablobm  · 技术社区  · 7 年前

    制造:取决于目标的可变需求

    我有一个 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) 决定运行什么规则时。不过,它是在运行规则时解决的。

    那么,我如何才能使这个工作呢?

    1 回复  |  直到 7 年前
        1
  •  2
  •   MadScientist    7 年前

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

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

    有多种方法可以处理这个问题。最简单的方法是将选择更改为使用变量而不是目标,然后使用 constructed macro names . 假设您将值存储在 LV 变量(不应使用 LANG 因为这对外壳来说是特别的),比如:

    # 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 (无效设置)您将得到一个错误。

    还有其他的方法可以做到这一点,但是如果没有完全理解你想要什么,我们就不能肯定地说。