[英]Execute Makefile target only if dependencies needed building
我有一個包含兩個“子項目”的項目和一個 Dockerfile,它結合了每個子項目的可執行文件。 目錄結構是這樣的:
Makefile
Dockerfile
proj1/Makefile
proj1/proj1-bin
proj1/...
proj2/Makefile
proj2/proj1-bin
proj2/...
我的頂級 Makefile 目前是這樣的:
container: proj1 proj2
docker build .
proj1:
make -C proj1
proj2:
make -C proj2
.PHONY: container proj1 proj2
我怎樣才能做到只有在重建 proj1 或 proj2 時才重建容器?
當目標被標記為.PHONY
,它總是會被重建,所以第一件事是擺脫虛假目標並依賴於實際文件,這些文件具有要比較的時間戳。 唯一的問題是如何發現一個容器已經構建; 處理這個問題的一種方法是在構建容器時創建一個時間戳文件 - 這將僅用作make
在決定是否重建目標時進行比較的時間戳。
時間戳文件應該取決於在子項目中創建的實際文件,以便將 docker build 時間戳與實際二進制文件進行比較,如果實際二進制文件更新,則將重新構建容器。 子項目反過來需要始終委托給$(MAKE)
因為只有子 Makefile 知道如何以及是否重建目標。 我們可以通過依賴虛假目標來實現這一點,這將使配方運行,但最終,如果文件本身沒有得到更新,它不會觸發更高級別目標的重建( container.timestamp
文件,因此容器不會重建)。
例子:
$ cat Makefile
.PHONY: container
container: container.timestamp
container.timestamp: proj1/proj1.bin proj2/proj2.bin
echo docker build .
touch $@
%.bin: FORCE
$(MAKE) -C $(@D)
.PHONY: FORCE
$ cat proj1/Makefile
proj1.bin:
touch $@
$ cat proj2/Makefile
proj2.bin:
touch $@
輸出:
$ make
make -C proj1
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
touch proj1.bin
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
make -C proj2
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
touch proj2.bin
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
echo docker build .
docker build .
touch container.timestamp
$ make
make -C proj1
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
make[1]: 'proj1.bin' is up to date.
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
make -C proj2
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
make[1]: 'proj2.bin' is up to date.
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
注意子生成文件是如何被調用的,但由於二進制文件沒有更新,容器也沒有更新。 但是,如果此更新,則將重建容器:
$ touch proj2/proj2.bin
$ make
make -C proj1
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
make[1]: 'proj1.bin' is up to date.
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj1'
make -C proj2
make[1]: Entering directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
make[1]: 'proj2.bin' is up to date.
make[1]: Leaving directory '/mnt/c/Users/raspy/git/so-68290730/proj2'
echo docker build .
docker build .
touch container.timestamp
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.