簡體   English   中英

如何在 Makefile 的后面部分覆蓋目標的先決條件?

[英]How to Override Prerequisites of a Target in Later part of Makefile?

有沒有辦法在 Makefile 的后面部分覆蓋目標的先決條件?

一個普通的 Makefile 被多個用戶使用。 為了適應個人的獨特用法,最后添加了一個包含指令。

例如,common.make

SomeVar1 =

all: step5

step1:
    recipe1

step2: step1
    recipe2

step3: step2
    recipe3

step4: step3
    recipe4

step5: step4
    recipe5

-include local.make

必要時,個人用戶可以在他/她自己的 local.make 中覆蓋來自 common.make 的變量甚至配方。

但是,似乎 common.make 的先決條件不能在 local.make 中被覆蓋。

例如,如果用戶需要跳過第 3 步和第 4 步,在 local.make 中添加以下內容不會刪除第 4 步作為第 5 步目標的先決條件。

step5: step2

GNU make 是否有一些語法來強制覆蓋 Makefile 前面部分中定義的目標的先決條件?

也許,像:

.OVERRIDE: step5: step2

我能想到的唯一方法是將 common.make 中的每個規則的先決條件定義為變量。 但是對於大量步驟來說,這將是笨拙的——要定義大量變量以及將變量名稱關聯/映射到它們的步驟需要單獨的文檔。

如果可能,我想避免使用先決條件變量方法。 希望 GNU make 有一些語法可以做得更好。

謝謝您的幫助。

氫氰酸

Make 有?=用於覆蓋行為:

-include local.make

# local.make definition of STEPX_PREREQS "overrides" below defaults
STEP1_PREREQS ?=
STEP2_PREREQS ?= step1
STEP3_PREREQS ?= step2

step1: $(STEP1_PREREQS)
    recipe1

step2: $(STEP2_PREREQS)
    recipe2

step3: $(STEP3_PREREQS)
    recipe3

我只是想到了一種解決方法,它不像所需的假設.OVERRIDE:但它不需要為 common.make 中的每個先決條件定義變量。

使用相同的 common.gmake 示例,如果用戶需要跳過 step3 和 step4,但需要在 step1 和 step2 之間添加 step1b 和 step1c,他/她的 local.make 將如下所示。

step1b: step1
    recipe1b

step1c: step1b
    recipe1c

step2: step1c

step3:
    :

step4:
    :

此外,GNU make 還會顯示有關 step3 和 step4 目標被覆蓋的警告消息,這很有幫助。

local.make:10: warning: overriding commands for target `step3'
local.make:13: warning: overriding commands for target `step4'
common.make:12: warning: ignoring old commands for target `step3'
common.make:15: warning: ignoring old commands for target `step4'

盡管如此,由於這實際上並沒有覆蓋依賴項,因此用戶必須強制對所有依賴項執行 no-op 以跳過。 在這種情況下,step3 和 step4 目標都需要無操作,在真正的 common.make 中,每個跳過的目標可能有多個先決條件。

這是我能想到的唯一問題。 我相信它甚至可以使用 -j 選項進行並行執行。

由於我無法預測用戶可能與 local.make 覆蓋結合使用的所有可能的 GNU make 選項,因此我沒有想到使用這種 local.make 覆蓋的任何潛在陷阱?

氫氰酸

獲得類似覆蓋行為的一種方法是利用模式匹配,偏好“最精確匹配”。 通過一個小模式使原始目標有點模棱兩可允許 local.make 用精確匹配覆蓋。

SomeVar1 =

all: step5

s%ep1:
    recipe1

s%ep2: step1
    recipe2

s%ep3: step2
    recipe3

s%ep4: step3
    recipe4

s%ep5: step4
    recipe5

-include local.make

如果在step5中有 step5 它比s%ep5更准確。

(我實際上並不喜歡這個解決方案,但你喜歡你,我只是帶來了技術。)

如果你願意,你可以添加:

step1b: step1
    touch "$@"

step1c: step1b
    touch "$@"

step2: step1c

在 local.make 中並像這樣調用:

$ make step2; make -t step4; make step5
touch "step1"
touch "step1b"
touch "step1c"
touch "step2"
touch step3
touch step4
touch "step5"

(在這里測試 makefile 我將 recipeN 替換為touch "$@"所以 touch with quote 是我的食譜,而 touch without 是由 GNU Make 打印的。)

我知道它有效,因為它非常線性。 如果不是,我可能只是使用make -n或類似的東西捕獲目標列表,然后執行這樣的命令行。

如果不是覆蓋您定義的: step1.make step2.make 並且您將它們全部包含在內,該怎么辦。 如果您通過腳本生成它們,那很好:您修改 stepN.make 但不是包括每個人的全局。 然后用戶可以選擇精確地覆蓋他想要的步驟。

所以 Makefile 會有這個形狀:

# WARNING feel free to modify this file but don't modify stepN.make
#
# If you have missing target double check it isn't defined
# in stepN.make directly or with pattern (%) rule
include step1.make
include step2.make
include step3.make

暫無
暫無

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

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