2014-09-29 65 views
0

這在試圖寫一個非遞歸化妝,我有以下塊:makefile文件如何轉成宏

dir := $(ROOT)/libs/libA/ 
include $(dir)/rules.mk 

dir := $(ROOT)/libs/libB/ 
include $(dir)/rules.mk 

dir := $(ROOT)/libs/libC/ 
include $(dir)/rules.mk 

這顯然是不必要的重複。我如何編寫一個宏來摺疊所有這些,以便我只需提供libA,libBlibC?我還需要在每個include之前設置dir

+0

我問你在另一篇文章,閱讀紙。 http://evbergen.home.xs4all.nl/nonrecursive-make.html它會回答很多,如果不是所有的問題。這是一篇很好的論文。我多次成功實施並擴展了本文的想法。有用。你讀過它,發現它不夠? – 2014-09-29 19:11:02

+0

@MarkGaleck - 我已經多次閱讀過,並且正在建立一些基於它的東西......這是一種需要的格式。我只是想簡化這一部分,這是不行的。 – Barry 2014-09-29 19:23:17

+0

好吧,我明白了。恕我直言,你可能會發現,你不能簡化這篇論文,因爲如果你正在構建一個大系統,最終你將需要它的所有元素。所以你不妨從一開始就實施它。例如,那裏有一個「目錄堆棧」。你現在可能不需要它,但是如果你想做遞歸包含,你將需要它。當然你需要遞歸包含。您無法脫離一個級別,就像無法脫離具有一級目錄的文件系統一樣。 – 2014-09-29 19:47:05

回答

1

以下是如何在每個子目錄列表中按順序包含rules.mk makefile,並使變量DIR等於每個rules.mk中的子目錄。我使用變量名DIR,而不是dir,因爲我相信makefile中的「全局」變量名應該是大寫的。

對於非遞歸makefile文件的其他實現細節,請諮詢

evbergen.home.xs4all.nl/nonrecursive-make.html

# include the makefile $2/rules.mk 
# and make the variable $1 be equal to the directory $2, inside that makefile 
define INCLUDE_DIR 
$1 := $2 
include $$($1)/rules.mk 
endef 

# do INCLUDE_DIR for directory variable name $1 and directories $2 
define INCLUDE_DIRS 
$(foreach dir, $2, $(eval $(call INCLUDE_DIR,$1, $(dir)))) 
endef 


DIRS := \ 
    $(ROOT)/libs/libA \ 
    $(ROOT)/libs/libB \ 


$(call INCLUDE_DIRS,DIR, $(DIRS)) 
+0

爲什麼只是'$(調用INCLUDE_DIRS,DIR,$(DIRS))'而不是'$(eval $(調用INCLUDE_DIRS,DIR,$(DIRS)))'? – Barry 2014-09-29 20:25:38

+0

@Barry,因爲代碼的前兩段是給你的,「管理員」,有些人知道通常編輯系統級文件的makefile。底部的兩個,放在你的個人遞歸makefile片段中,並由該片段維護者編輯,通常是希望儘可能簡單化所有內容的人。所以爲了他們的利益,有一個簡單的函數調用,所以他們不需要知道任何關於'eval'等的東西。 – 2014-09-29 20:30:35

+0

@Barry通過上面的設置,不需要再次調用'eval'。這對於希望讓所有事情變得簡單的「用戶」都是有益的。我不會解釋爲什麼它不需要:)(下面「教一個男人去釣魚」):) – 2014-09-29 20:33:17

1
LIBS := libA libB libC 

include $(patsubst %, $(ROOT)/libs/%/rules.mk, $(LIBS)) 
+0

對不起,我應該澄清一下,我還需要在每個include之前設置'dir'。我怎樣才能做到這一點?我編輯了我的問題。 – Barry 2014-09-29 17:41:45

+0

@Barry:聽起來像[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – Beta 2014-09-29 21:32:04

+0

@貝塔他之所以問這個問題,是因爲他需要它。在進行非遞歸make時,必須具有與每個目錄makefile片段中的「當前目錄」相等的變量。當你實現了一個目錄堆棧時,這個變量值在一個堆棧中,每當你包含一個makefile時,當你結束解析該makefile時,新的值被放到一個堆棧上,離開堆棧。 – 2014-09-30 18:07:03

0

如果你能夠使用GNU做,下面應該工作:

get_mk := $(ROOT)/libs/$(1)/rules.mk 

include $(call get_mk,libA) 
include $(call get_mk,libB) 
include $(call get_mk,libC) 

你可以在http://www.gnu.org/software/make/manual/make.html#Call-Function得到call更多信息。

+0

對不起,我應該澄清,我需要在每個包含之前設置dir。我怎樣才能做到這一點?我編輯了我的問題。 – Barry 2014-09-29 18:10:29

+0

@巴里,你可以使用其他帖子的答案有一個'包括'行而不是三個。但是,我不知道如何避免必須設置三次「dir」。 – 2014-09-29 18:24:56