簡體   English   中英

僅當需要構建依賴項時才執行 Makefile 目標

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM