2012-09-14 81 views
0

我基本上看着一個越野車生成文件,這使我與以下方案混淆。Makefile:需要明確混合使用環境變量和變量

default: 
    echo "Build started with [email protected] at $(ENV_VAR)";\ 
    ENV_VAR=$(NEW_DIR); \ 
    cd $(ENV_VAR); \ 
    $(MAKE); 

目的的程序員的:

基本上程序員已經打算重寫該環境變量ENV_VAR用一個新的值(一個目錄路徑)NEW_DIR,然後執行補充遞歸地在該目錄內。

錯誤在此生成的文件:

的錯誤,我看到的是編碼器已經使用「CD $(ENV_VAR)」代替「CD $$(ENV_VAR)」。因此,我們實際上沒有使用「cd」命令的overriden make變量,而是在執行$(MAKE)之前仍然使用環境變量的值。此外,由於不存在路徑,cd命令失敗。最後,我們最終做了遞歸make。

問題我有

正如我在上面的段落中提到,我們在遞歸化妝的場景。有趣的是,我看到的是第二次調用同一個目標時,我看到$(ENV_VAR)反映了NEW_DIR的重寫值。這讓我感到困惑。

樣本輸出:

假設:

NEW_DIR = /新DIR OLD-DIR = /老DIR

輸出:

Build started with default at /old-dir 
bin/sh /old-dir: no such file (or) directory 
Build started with default at /new-dir 

任何建議在此請。

回答

1

你是對的$(ENV_VAR)是不正確的。但是$$(ENV_VAR)也不正確。

Make在命令中展開變量,然後將命令傳遞給shell,shell自行展開。所以

default: 
    echo "Build started with [email protected] at $(ENV_VAR)";\ 
    ENV_VAR=$(NEW_DIR); \ 
    cd $(ENV_VAR); \ 
    $(MAKE); 

成爲一個shell命令

echo "Build started with [email protected] at /old_dir";\ 
ENV_VAR=/new_dir; \ 
cd /old_dir; \ 
make 

該命令還沒有被執行;這項任務尚未完成,現在已經太晚了。

建議的解決方案也不起作用。這:

default: 
    echo "Build started with [email protected] at $(ENV_VAR)";\ 
    ENV_VAR=$(NEW_DIR); \ 
    cd $$(ENV_VAR); \ 
    $(MAKE); 

變成這樣:

echo "Build started with [email protected] at /old_dir";\ 
ENV_VAR=/new_dir; \ 
cd $(ENV_VAR); \ 
make 

這看起來不錯,但是請注意,cd $(ENV_VAR);語法,而不是shell語法(至少不是bash)的。正確的shell語法是cd $ENV_VAR,所以規則應該是:

default: 
    echo "Build started with [email protected] at $(ENV_VAR)";\ 
    ENV_VAR=$(NEW_DIR); \ 
    cd $$ENV_VAR; \ 
    $(MAKE); 

the manual「在默認情況下,只有從環境或命令行來變量傳遞給遞歸調用」(但是你可以重寫這種行爲如果你選擇)。由於ENV_VAR是一個環境變量,因此它將被傳遞給子版本,並且如果在命令shell中對其進行修改,則子版本將會收到修改後的值。

最後,我建議你試試這樣說:

default: 
    echo "Build started with [email protected] at $(ENV_VAR)"; 
    Make -C $(NEW_DIR) ENV_VAR=$(NEW_DIR); 
+0

優秀的解釋!非常感謝 –