使用Make从路径/目录中提取字符串

问题描述 投票:1回答:1

我有一个具有多个git repo的Makefile,需要克隆我使用以下有效的方法

clone:
    git clone https://github.company.corp/dev-wi/ws-led.git
    git clone https://github.company.corp/dev-wi/tools-extension.git
    git clone https://github.company.corp/dev-wi/javt-ra.git

虽然以下代码有效,但我想为列表中的所有存储库循环执行类似的操作

build:
    cd ws-led;  \
    docker build -t ws-led .
    cd tools-extension;  \
    docker build -t tools-extension .
    ...

对于每个回购,我需要更改目录并运行docker build,我想避免一遍又一遍地做这个...我知道我需要在/ dev-wi /之后提取字符串,因为这是我需要在其上运行docker build的repo目录。既然我有很多回购协议,我该如何轻松实现呢?

我尝试使用子集,但是我也有git命令(在克隆中),所以它不起作用,知道吗?

更新我创建了一个新的生成文件,仅使用此代码(ws-ledtools-extension是与生成文件处于同一级别的文件夹

repos := ws-led tools-extension

.PHONY: all

all: $(patsubst%,%/docker-build.log,$(repos))

%/docker-build.log: %/.git
    cd $*; docker build -t $* . >&2 | tee docker-build.log

我有错误:

make: Nothing to be done for all'.`

我在这里想念什么?

我尝试简化它,但删除git,然后说该文件夹(存储库)位于makefile的同一级别上

UPDATE

我将makefile更改为根目录

proj
  - ws-led
  — Dockerfile
 -tools-ext
 —Dockerfile    
-Makefile

我尝试以下操作

all: pre docker-build
.PHONY: pre docker-build
repos := ws-led tools-ext

pre:
    $(patsubst %,%docker-build,$(repos))

docker-build:pre
    cd $*; docker build -t $* . >&2 | tee docker-build

当我运行时出现以下错误

ws-leddocker-build  ws-leddocker-build
make: ws-leddocker-build: No such file or directory

任何想法?

linux bash makefile gnu-make gnu
1个回答
2
投票

循环通常是您要避免的事情。相反,为每个存储库声明一系列目标。

repos := ws-led tools-extension javt-ra

.PHONY: all clone
all: $(patsubst %,%/.built,$(repos))
clone: $(patsubst %,%/.git,$(repos))

%/.built: %/.git
    cd $*; docker build -t $* .
    touch $@

%/.git:
    git clone https://github.company.corp/dev-wi/$*.git

.built标志文件有点像疣,可以用更有用的东西替换,例如,docker build的输出。

all: $(patsubst %,%/docker-build.log,$(repos))

%/docker-build.log: %/.git
    cd $*; docker build -t $* . >&2 | tee docker-build.log

我们通常尝试避免循环的原因是允许make正确执行其主要工作-避免在目标已经更新时重新运行命令。因此,例如,如果您仅更改了ws-led,那么您也不想强制也重建其他两个。

已经说过,$(patsubst ...)是各种各样的循环;它基本上遍历repos并在每个文本周围创建一小段文本。没有patsubst,我们可以写

all: ws-led/.built tools-extension/.built javt-ra/.built

简单地说,要制作all,我们需要制作这三个;然后

%/.built: %/.git

表示对于任何与模式匹配的内容,它取决于后跟/.git的同一词干。因此,在原本为空的目录中,make会发现

  • 要制作all,我们需要制作ws-led/.builttools-extension/.builtjavt-ra/.built
    • 要制作ws-led/.built,我们需要制作ws-led/.git;
      • 制作ws-led/.git,我们需要
      git clone https://github.company.corp/dev-wi/ws-led.git
      
      • 然后满足此先决条件后,
      cd ws-led; docker build -t ws-led .
      touch ws-led/.built
      
    • 要制作tools-extension/.built,我们需要制作tools-extension/.git;
      • 制作tools-extension/.git,我们需要
      git clone https://github.company.corp/dev-wi/tools-extension.git
      
      ...等。

[将来,当make发现ws-ledws-led/.built更新时,它将重新构建它;但如果不是这样,它将得出结论,其他目标不需要做任何工作。这就是我们避免不必要地构建事物的方式。但显然,它要求Makefile正确包含每个相关依赖项的形式化。 (在这种情况下,理想情况下,您希望有一种方法可以知道何时更改了Git上游,并且需要由本地Makefile拉取某些内容;如果本地Git克隆没有这样做,那么当前这只是将一切视为已完成收到任何更新。)

© www.soinside.com 2019 - 2024. All rights reserved.