簡體   English   中英

makefile 和先決條件中的目標特定變量

[英]Target-specific variables in a makefile & prerequisites

我在 GNU make 中看到目標特定變量的意外結果。

我想要的是設置一個影響依賴關系的特定於目標的變量。 我可以使用.SECONDEXPANSION來實現。

some-target: DEP := debug-dep

debug: some-target

.SECONDEXPANSION:
some-target: $$(DEP)
    @echo $^

debug-dep:

make debug打印debug-dep


現在我讀到make 為后代規則定義了特定於目標的變量

當您定義特定於目標的變量時,該變量值也對該目標的所有先決條件及其所有先決條件等有效。

但是當我更改我的 makefile 以在“父”目標上設置變量時:

debug: DEP := debug-dep

debug: some-target

.SECONDEXPANSION:
some-target: $$(DEP)
    @echo $^

debug-dep:

make debug ,我得到一個空行。

這似乎與目標特定變量的記錄行為相矛盾。 有什么我想念的嗎?


這有點類似於make: Using target specific variables in prerequisites ,但我所做的是行不通的。

我相信這里的問題是在目標運行之前不會設置特定於目標的變量(如果在第二種情況下將@echo '$(DEP)'some-target主體,您將看到它已設置)但第二次擴展是在初始讀入階段后立即發生的。

我要說的是,我真的很驚訝這在第一種情況下工作(並推測為什么),但后來我把手冊拉了一分鍾,在閱讀.SECONDEXPANSION我發現了以下內容

[T]當您發現二次擴展始終發生在該目標的自動變量范圍內時,此功能的真正力量才會變得明顯。 這意味着您可以在第二次擴展期間使用$ @,$ *等變量,它們將具有預期值,就像在配方中一樣。 你所要做的就是通過逃避$來推遲擴張。 此外,顯式和隱式(模式)規則都會發生二次擴展。

這完全解釋了你的行為。 擴展僅查看在目標范圍內設置的變量,並且先決條件繼承僅在目標評估時發生(因為它取決於目標先決條件)。

所有變量都在第一個讀入階段設置。 無論是全局變量,還是特定於目標的變量(或特定於模式的變量)都是如此。

沒有像其他答案所說的那樣的東西

在運行目標之前,不會設置特定於目標的變量

請參見下面的示例 Makefile,

GA = ga
GB = $(GA)
GC := $(GA)

a: aTA = $(GA)
a: aTB := $(GA)
a: aTC = $(aTA)
a: b;
GA = ga2

b: bTA = $(aTA)
b: bTB := $(aTA)
b: bTC := $(bTA)
b:;

在第一個讀入階段之后,設置所有變量(因此, aTBga ,而不是ga2 )。 它們分別如下,

  • GA是字面的ga2
  • GB 是文字$(GA)
  • GC是字面的ga
  • aTA 是文字$(GA)
  • aTB 是字面上的ga
  • aTC 是文字$(aTA)
  • bTA 是文字$(aTA)
  • bTB 是字面意思 (空的)
  • bTC是字面意思 (空的)

雖然都設置好了,但是並不是處處可見,他們有scope。例如,

  • 全局變量 scope 無處不在
  • 目標特定變量的 scope 是
    • 目標的其他特定於目標的變量

    • 目標的配方

    • 目標先決條件的配方

      如果我們在目標b的配方中使用bTA ,這是我們可以看到bTA最終擴展到ga2的唯一原因。

    • 使用.SECONDEXPANSION時出現在目標規則中的先決條件文字

      這就是為什么 OP 問題中的第一個案例有效。

以下不是目標特定變量的 scope,

  • 父目標中的任何地方

  • 目標先決條件的特定於目標的變量

    這就是為什么bTBbTC都是空的。

  • 出現在目標先決條件規則中的(子)先決條件文字(無論是否使用.SECONDEXPANSION

    這就是為什么 OP 問題中的第二種情況不起作用的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM