使用 Make 从 path/dir 中提取字符串
Extract string from path/dir using Make
我有一个 Makefile,其中包含多个 git 需要克隆的存储库
我使用以下有效的
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 构建,
我想避免一遍又一遍地这样做......
我知道我需要在 /dev-wi/ 之后提取字符串,因为这是我需要 运行 docker 构建的 repo 目录。
因为我有很多回购协议,我怎么能轻松做到呢?
我尝试使用子集,但是我也有 git 命令(在克隆中)所以它不起作用,知道吗?
更新
我创建了一个新的 makefile 并仅使用此代码(ws-led
和 tools-extension
是 makefile
同一级别的文件夹
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
所有'.`
我在这里错过了什么?
我尝试简化它但删除了 git 并假设文件夹(repo)存在于 makefile
的同一级别
更新
我将 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
当我运行 make 时出现以下错误
ws-leddocker-build ws-leddocker-build
make: ws-leddocker-build: No such file or directory
有什么想法吗?
循环通常是您要避免的事情。相反,为每个 repo 声明一系列目标。
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/.built
、tools-extension/.built
和javt-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-led
比ws-led/.built
更新时,会重新构建;但如果不是,它将得出结论,不需要为其他目标做任何工作等。这就是我们避免不必要地构建事物的方式;但它显然要求 Makefile
正确包含每个相关依赖项的形式化。 (在这种情况下,理想情况下,您希望有一种方法可以知道 Git 上游何时发生变化,并且需要由本地 Makefile
拉取某些内容;如果本地 Git 克隆尚未收到任何更新。)
我有一个 Makefile,其中包含多个 git 需要克隆的存储库 我使用以下有效的
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 构建, 我想避免一遍又一遍地这样做...... 我知道我需要在 /dev-wi/ 之后提取字符串,因为这是我需要 运行 docker 构建的 repo 目录。 因为我有很多回购协议,我怎么能轻松做到呢?
我尝试使用子集,但是我也有 git 命令(在克隆中)所以它不起作用,知道吗?
更新
我创建了一个新的 makefile 并仅使用此代码(ws-led
和 tools-extension
是 makefile
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
所有'.`
我在这里错过了什么?
我尝试简化它但删除了 git 并假设文件夹(repo)存在于 makefile
的同一级别更新
我将 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
当我运行 make 时出现以下错误
ws-leddocker-build ws-leddocker-build
make: ws-leddocker-build: No such file or directory
有什么想法吗?
循环通常是您要避免的事情。相反,为每个 repo 声明一系列目标。
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/.built
、tools-extension/.built
和javt-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-led
比ws-led/.built
更新时,会重新构建;但如果不是,它将得出结论,不需要为其他目标做任何工作等。这就是我们避免不必要地构建事物的方式;但它显然要求 Makefile
正确包含每个相关依赖项的形式化。 (在这种情况下,理想情况下,您希望有一种方法可以知道 Git 上游何时发生变化,并且需要由本地 Makefile
拉取某些内容;如果本地 Git 克隆尚未收到任何更新。)