2010-05-13 57 views

回答

476

您有幾種選擇,從你的makefile外設立變量:

  • 從環境 - 每個環境變量轉化爲具有相同的名稱和值一個makefile變量。

    您可能還需要在設置-e選項(又名--environments-override),和你的環境變量將覆蓋製作成生成文件(除非這些分配自己使用override directive,但不推薦,這是更好的,靈活的分配使用?=分配(條件變量賦值操作符,它只有一個效果,如果變量沒有定義):

    FOO?=default_value_if_not_set_in_environment 
    

    注意,某些變量不會從環境中繼承:

    • MAKE從名的腳本
    • SHELL得到或者是生成文件內設置,或默認爲/bin/sh(理由:命令生成文件內指定的,而且他們殼特異性)。
  • 從命令行 - make可以變量賦值爲他的命令行的一部分,目標調和

    make target FOO=bar 
    

    但隨後makefile文件中的所有任務,以FOO變量將被忽略除非您在作業中使用override directive。 (效果與環境變量的-e選項相同)。

  • 從父導出使 - 如果你調用從一個Makefile做,你通常應該沒有明確寫變量賦值是這樣的:

    # Don't do this! 
    target: 
         $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS) 
    

    取而代之的是,更好的解決方案可能是出口這些變量。導出一個變量使其進入每個shell調用的環境,並且使得來自這些命令的調用按照上面的指定選擇這些環境變量。

    # Do like this 
    CFLAGS=-g 
    export CFLAGS 
    target: 
         $(MAKE) -C target 
    

    您還可以通過使用export不帶參數的出口所有變量。

+3

從命令行傳遞給空格做''make A ='「作爲df」'''' – 2013-01-16 17:27:24

+2

好像你在問關於環境變量的問題。首先,它是一個調試噩夢,如果它在地方A而不在地方B,僅僅因爲他們有不同的環境。 – 2013-01-30 01:00:12

+0

它實際上拼寫 - 環境覆蓋 – user7610 2013-11-23 11:13:49

115

最簡單的方法是:

make foo=bar target 

然後在你的makefile,你可以參考$(foo)。請注意,這不會自動傳播給子版本。

如果您使用的子品牌,看到這篇文章:Communicating Variables to a Sub-make

+2

by sub-make you mean to makefiles'included' in the main makefile? – Pablo 2010-05-13 10:49:25

+2

@Michael:這意味着從makefile中再次調用make。我已經更新了我的答案,因爲您似乎對這個細節感興趣。 – 2010-05-13 10:54:19

35

說你有一個這樣的生成文件:

action: 
    echo argument is $(argument) 

你可以這樣調用它make action argument=something

+2

所以目標和參數可以在位置方面互換? – Pablo 2010-05-13 10:40:16

+3

@邁克爾:是的(見馬克·拜爾斯的回答) – nc3b 2010-05-13 10:42:41

16

manual

make中的變量可以來自運行的環境。每個啓動時看到的環境變量都會被轉換爲具有相同名稱和值的make變量。但是,makefile中的顯式賦值或命令參數會覆蓋環境。

所以,你可以(從bash)的事:

FOOBAR=1 make 

導致你的Makefile變量FOOBAR

+0

我不喜歡環境的方式,但是謝謝 – Pablo 2010-05-13 10:39:40

+1

另一種方式幾乎在所有情況下都更好。爲了完整性,我會在這裏留下。 – Thomas 2010-05-13 10:58:00

2

如果你犯了一個名爲makefile文件,添加一個變量這樣$(單元測試) ,那麼你就可以使用這個變量Makefile裏甚至使用通配符

例如:

make unittest=* 

我使用BOOST_TEST並給出通配符參數--run_test = $(unittest) 然後我將能夠使用正則表達式來過濾測試我想讓我的Makefile 運行

1

這裏有沒有引用其他選項,包括在GNU由斯托曼和麥格拉斯(見http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html)製作的書。它提供了示例:

archive.a: ... 
ifneq (,$(findstring t,$(MAKEFLAGS))) 
     +touch archive.a 
     +ranlib -t archive.a 
else 
     ranlib archive.a 
endif 

它涉及驗證給定參數是否出現在MAKEFLAGS中。例如..假設你正在學習關於C++ 11中的線程,並且已經將你的學習分成了多個文件(class01,...,classNM),並且你想要:編譯然後所有並單獨運行或編譯一個並且如果指定了一個標誌(例如-r),則運行它。所以,你能想出以下Makefile

CXX=clang++-3.5 
CXXFLAGS = -Wall -Werror -std=c++11 
LDLIBS = -lpthread 

SOURCES = class01 class02 class03 

%: %.cxx 
    $(CXX) $(CXXFLAGS) -o [email protected] $^ $(LDLIBS) 
ifneq (,$(findstring r, $(MAKEFLAGS))) 
    ./[email protected] 
endif 

all: $(SOURCES) 

.PHONY: clean 

clean: 
    find . -name "*.out" -delete 

有了這樣的,你會:

  • 構建和運行文件瓦特/ make -r class02;
  • 構建全部w/makemake all;
  • 構建和運行所有W/make -r(假設它們都含有一定的那種斷言的東西,你只是想測試他們全部)
2
export ROOT_DIR=<path/value> 

然後使用Makefile中的變量,$(ROOT_DIR)