2015-12-09 32 views
2

我有一種情況,我需要根據遠程文件執行make中的規則。這是我想要做的一個例子(實際的Makefile是不相關的方式在這裏有很多更復雜):依賴遠程文件中的make

URL = http://cdn.sstatic.net/stackoverflow/img/favicon.ico 

stackoverflow.png: favico.ico modified | check_modified 
    convert favicon.ico [email protected] 

check_modified: modified 
    @echo Icon was modified. Downloading. 
    rm -f favicon.ico 
    wget $(URL) 

.PHONY: check_modified 

favico.ico: check_modified 

modified: 
    touch -d "`wget --spider -S $(URL) 2>&1 | sed -n 's/.*Modified: //p'`" [email protected] 

的理念是:

  • 規則建modified應該總是被運行。該規則的功能是將文件的修改時間更改爲與URL所指向的修改時間相同。
  • 之後,我想要modified就依賴性而言正常運行。如果modifiedfavicon.ico更新,我想檢索新文件,然後讓依賴關係導致重新創建目標文件。

作爲一個皺紋,在某些應用程序中,我必須手動檢索文件。在這些情況下,我想只有一條規則會觸發並告訴我手動下載文件,但這不會影響構建目標。例如,如果我要轉換的源圖像位於網站登錄名後面,則需要手動登錄到網站並將其下載到固定位置,然後重新運行make。

一切我已經試過兩種:

  • 無法查詢的網址,如果目標是最新的,或者
  • 總是檢查URL和重建目標,即使modified是不是更近比目標。

任何智慧的話?

回答

3

您的問題可能是在運行任何配方之前,先建立依賴關係圖。因此,當您創建/更新標記文件時,要考慮其最後修改日期並用它來決定是否要構建其他目標還爲時過晚。

您的第一個觀察到的行爲(未能檢查URL,如果目標是最新的)可能對應於您未使用.PHONY特殊目標的嘗試。一旦創建了modified,make始終認爲它是最新的,因爲它沒有先決條件,因此不能過時。

第二行爲(總是檢查URL和重建目標,即使修改爲不大於目標更近)對應於你貼什麼:check_modified.PHONY特殊目標的先決條件,這迫使作出始終認爲它已過時。 stackoverflow.pngfavico.ico,直接與否,取決於check_modified,因此也總是被視爲過期。

解決您的問題的一個選擇是使用遞歸兩遍make調用。在第一次運行時,make將生成all假目標(始終),更新modified標記文件,然後再次調用自己以構建其他具有標記文件作爲先決條件並已過時的目標。因爲對於第二次調用,重建它的依賴關係圖,它將考慮標記文件的最後修改日期。喜歡的東西:

URL = http://cdn.sstatic.net/stackoverflow/img/favicon.ico 

.PHONY: all 

all: 
    touch -d "`wget --spider -S $(URL) 2>&1 | sed -n 's/.*Modified: //p'`" modified 
    $(MAKE) stackoverflow.ico 

stackoverflow.ico: modified 
    @echo Icon was modified. Downloading.; \ 
    rm -f favicon.ico; \ 
    wget $(URL); \ 
    convert favicon.ico [email protected] 

說明:

  • 我換成你轉換到png由一個無用的轉換ico因爲這樣favicon.ico圖標是複合材料和其轉化爲png創建兩個文件,而不是一個名爲stackoverflow-0.pngstackoverflow-1.png,無用地使事情複雜化。
  • all是一個真正的假目標和默認目標,所以每次調用make(或make all)時,都會生成它。它首先更新modified標記文件,然後再次調用make生成stackoverflow.ico
  • 如果stackoverflow.icomodified更新,則第二次make調用不起作用,否則它會下載並轉換。

第二個問題(獲取有關所需手動操作的消息)是完全不同且更易於解決的問題。讓我們先定義一個消息,並在文件的食譜呼應它:

define DIY_message 
Dear user, you should first: 
- do this 
- and that. 
Unless you know it is useless, of course. 
endef 
export DIY_message 

the_remote_file: 
    @echo "$$DIY_message" 

該消息將如化妝與此目標(make the_remote_file)調用打印或以某種方式取決於the_remote_file以及一個目標:

  • the_remote_file不存在,
  • the_remote_file存在,但外的日期相對於它的先決條件(如果你宣佈它的先決條件),
  • the_remote_file.PHONY的先決條件。

注意:使用由define-endef分配的中間變量變量可使格式化的多行消息變得更容易。