例如,我在我的Makefile是這樣的:如何在makefile中寫入'cd'命令?
all:
cd some_directory
但是,當我輸入make
我看到的只是「CD some_directory」,像在echo
命令。
例如,我在我的Makefile是這樣的:如何在makefile中寫入'cd'命令?
all:
cd some_directory
但是,當我輸入make
我看到的只是「CD some_directory」,像在echo
命令。
它實際上正在執行命令,將目錄更改爲some_directory
,但是,這是在子進程shell中執行的,並且不影響make和您正在使用的shell。
如果您要在some_directory
範圍內執行更多任務,則需要添加一個分號並附加其他命令。請注意,您不能使用換行符,因爲它們被make解釋爲規則的結尾,因此爲清晰起見使用的任何換行符都需要使用反斜槓進行轉義。
例如:
all:
cd some_dir; echo "I'm in some_dir"; \
gcc -Wall -o myTest myTest.c
還要注意分號是每一個命令之間必要的,即使你加一個反斜槓和一個換行符。這是由於整個字符串被shell解析爲一行。正如評論中指出的那樣,您應該使用'& &'來加入命令,這意味着只有在前面的命令成功時纔會執行它們。
all:
cd some_dir && echo "I'm in some_dir" && \
gcc -Wall -o myTest myTest.c
做破壞性的工作,如清理時,你會否則將會破壞錯了東西,應cd
失敗不管出於什麼原因,這一點尤爲重要。
雖然常用的方法是在子目錄中調用make,但您可能需要查看該子目錄。有此一命令行選項,這樣你就不用調用cd
自己,所以你的規則是這樣的
all:
$(MAKE) -C some_dir all
這將改變成some_dir
,並在那裏與目標「的所有」執行Makefile
。作爲最佳實踐,使用$(MAKE)
而不是直接調用make
,因爲它會小心地調用正確的make實例(例如,如果您爲構建環境使用特殊的make版本),並提供稍微不同的行爲運行時使用某些開關,如-t
。
對於記錄,使總是回聲它執行的命令(除非明確禁止),即使它沒有輸出,這就是你所看到的。
那麼,不*總是*。爲了抑制回聲,只需在該行的開頭添加@。 – Beta
@Beta:好的,並且破折號前綴也會忽略錯誤狀態。也許我有點失落了,我想指出這樣一個事實,即無論命令是什麼,命令都會迴應命令。在這種情況下,這是一個沒有輸出的命令,這讓不熟悉make的人看起來更加陌生。 – falstro
兩個nits:1.這些命令應該真的被'&&'連接,因爲用';'如果目錄不存在並且'cd'失敗,shell將繼續運行當前目錄中的其餘命令,這可能會導致諸如編譯時發現神祕的「文件未找到」消息,調用make時出現無限循環,或者像'clean :: cd dir; rm -rf *'。 2.調用子make時,調用'$(MAKE)'而不是'make',以便[選項將正確傳遞](http://www.gnu.org/software/make/manual/make.html #MAKE-變量)。 – andrewdotn
一旦到達那裏,你想要它做什麼?每個命令都在子shell中執行,因此子shell會更改目錄,但最終結果是下一個命令仍在當前目錄中。
用GNU做,你可以這樣做:
BIN=/bin
foo:
$(shell cd $(BIN); ls)
爲什麼'$(shell ...)'時出現cd $(BIN); ls'或'cd $(BIN)&& ls'(就像@andrewdotn指出的)就足夠了。 – vapace
這裏有一個可愛的把戲對付目錄而作。而不是使用多行字符串,或「cd;」每個命令,定義了一個簡單的chdir函數像這樣:
CHDIR_SHELL := $(SHELL)
define chdir
$(eval _D=$(firstword $(1) $(@D)))
$(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL))
endef
然後,所有你需要做的就是把它在你的規則,像這樣:
all:
$(call chdir,some_dir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
你甚至可以做到以下幾點:
some_dir/myTest:
$(call chdir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
「可愛」?更像是有足夠的繩子在腳下射擊自己。 – tripleee
這個當前目錄是爲那些只在該規則中的命令設置的,還是爲所有後來執行的規則設置的?此外,將在Windows下這項工作的一些變化? – user117529
這當然會破壞並行執行('-jn'),這是_make_的全部重點。 – bobbogo
從GNU make 3.82
開始,您可以使用.ONESHELL
特殊目標在外殼的單實例運行所有食譜線:
- 新的特殊目標:
.ONESHELL
指示作出調用單個實例的外殼 並提供其與整個配方,不管它有多少 線包含的內容。 [...]
例子:
.ONESHELL:
all:
cd ~/some_dir
pwd # this line is correctly run in ~/some_dir if cd succeeded
像這樣:
target:
$(shell cd ....); \
# ... commands execution in this directory
# ... no need to go back (using "cd -" or so)
# ... next target will be automatically in prev dir
祝你好運!
目前還不清楚你想做什麼,但是,根據我對'make'的經驗,我從來不想改變這個目錄。也許你應該嘗試另一種解決方案? –
相信你的目錄很重要,這是一個常見的新手錯誤。對於大多數情況來說,它不是; 'cd dir; cmd文件幾乎總是可以用'cmd dir/file'來表示。 – tripleee
這是一個常見的新手錯誤,相信你目前的工作目錄是無足輕重的。許多程序,特別是shell腳本,都是以「。」爲特定的值寫入的。 的確,大多數工具都是這樣設計的,你不需要爲它改變你的密碼。但這並非總是如此,我認爲將其稱爲「錯誤」以相信您的目錄可能很重要是個好主意。 –