为什么Makefile表达式中的Bash不';不行?

为什么Makefile表达式中的Bash不';不行?,bash,makefile,gnu-make,Bash,Makefile,Gnu Make,直接粘贴到我的shell中,下面的代码尝试了3个正则表达式中的每一个,并且可以正常工作(请参见*。{jpg,png,gis.tif}): 作为makefile进程,它会失败并返回: task: for file in ./output/India/*.{png,jpg,gis.tif} ; \ do echo $$file ; openssl base64 -in $$file -out ./output/India/`basename $$file`.b64; \ done

直接粘贴到我的shell中,下面的代码尝试了3个正则表达式中的每一个,并且可以正常工作(请参见
*。{jpg,png,gis.tif}
):

作为makefile进程,它会失败并返回:

task: 
  for file in ./output/India/*.{png,jpg,gis.tif} ; \
    do echo $$file ; openssl base64 -in $$file -out ./output/India/`basename $$file`.b64; \
  done
47910543179104:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('./output/India/*.{png,jpg,gis.tif}','r')
并返回:

task: 
  for file in ./output/India/*.{png,jpg,gis.tif} ; \
    do echo $$file ; openssl base64 -in $$file -out ./output/India/`basename $$file`.b64; \
  done
47910543179104:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('./output/India/*.{png,jpg,gis.tif}','r')

当Bash位于makefile中时,为什么此表达式不起作用?

make默认使用
/bin/sh
,并且不支持大括号扩展


通过在makefile中设置
shell
变量,告诉make使用不同的shell,不要在make规则中使用大括号扩展,或者运行脚本而不是内联配方(哪个脚本可以由
bash
/等运行)。

make默认使用
/bin/sh
,并且它不支持大括号扩展


通过在makefile中设置
shell
变量,告诉make使用不同的shell,不要在make规则中使用大括号扩展,或者运行脚本而不是内联配方(哪个脚本可以由
bash
/等运行)。

我被提示给出make如何为您完成繁重工作的草图

因此,您希望将
output/India/
中的所有源文件(
.jpg
.png
.gis.tif
)转换为它们的base64编码等效文件。草图:

.PHONY: all
all: # default target

dir := output/India/
exts := jpg png gis.tif
wildcards := $(addprefix ${dir}*.,${exts})
sources := $(wildcard ${wildcards})
targets := $(addsuffix .b64,${sources})

${targets}: %.b64: %
     openssl base64 -in $< -out $@

all: ${targets}
all: ; : $@ Success
。假冒:全部
全部:#默认目标
dir:=输出/印度/
exts:=jpg png gis.tif
通配符:=$(addprefix${dir}*,${exts})
来源:=$(通配符${wildcards})
目标:=$(addsuffix.b64,${sources})
${targets}:%。b64:%
openssl base64-输入$<-输出$@
全部:${targets}
全部:;:$@成功
这比它需要的更详细,通常我反对使用
$(通配符…
)。哦,好吧

那么与shell版本相比,我们有什么优势呢

  • make-j5
    将同时进行5次转换。如果你有四个CPU就好了
  • 转换在第一个错误时停止(例如磁盘已满)
  • 自上次转换以来未更改的文件不会重新转换
  • 没有不可靠的shell语法(尽管sh是make的重要组成部分)

  • 未经测试顺便说一句。对不起。

    我被提示给你一个草图,说明make如何为你完成这项繁重的工作

    因此,您希望将
    output/India/
    中的所有源文件(
    .jpg
    .png
    .gis.tif
    )转换为它们的base64编码等效文件。草图:

    .PHONY: all
    all: # default target
    
    dir := output/India/
    exts := jpg png gis.tif
    wildcards := $(addprefix ${dir}*.,${exts})
    sources := $(wildcard ${wildcards})
    targets := $(addsuffix .b64,${sources})
    
    ${targets}: %.b64: %
         openssl base64 -in $< -out $@
    
    all: ${targets}
    all: ; : $@ Success
    
    。假冒:全部
    全部:#默认目标
    dir:=输出/印度/
    exts:=jpg png gis.tif
    通配符:=$(addprefix${dir}*,${exts})
    来源:=$(通配符${wildcards})
    目标:=$(addsuffix.b64,${sources})
    ${targets}:%。b64:%
    openssl base64-输入$<-输出$@
    全部:${targets}
    全部:;:$@成功
    
    这比它需要的更详细,通常我反对使用
    $(通配符…
    )。哦,好吧

    那么与shell版本相比,我们有什么优势呢

  • make-j5
    将同时进行5次转换。如果你有四个CPU就好了
  • 转换在第一个错误时停止(例如磁盘已满)
  • 自上次转换以来未更改的文件不会重新转换
  • 没有不可靠的shell语法(尽管sh是make的重要组成部分)

  • 未经测试顺便说一句。对不起。

    好的,按照你的回答,我对它进行了粗暴的处理:
    对于文件in./output/$(NAME)/*.png./output/$(NAME)/*.jpg./output/$(NAME)/*.gis.tif
    :DOk,按照你的回答,我对它进行了粗暴的处理:
    对于文件in./output/$(NAME)/*.png./output/$(NAME)/*.jpg/$(NAME)/*.gis.tif
    :调整提示:如果您发现自己在make中为循环编写了一个shell
    ,那么您可能做错了。这里您正在将
    .png
    转换为
    .b64
    (例如)。这听起来像是一份直接为make做的工作。这样做有很多好处:增量构建、并行操作、错误检查…@bobbogo:谢谢你的评论,你有什么实际的例子可以展示/链接,让我们可以学习你的方法吗?请随意以您处理此问题的方式发布答案,这将有助于善意学习者,我肯定会+1。只是一个提示:如果您发现自己在make中为
    循环编写shell
    ,那么您可能做错了。这里您正在将
    .png
    转换为
    .b64
    (例如)。这听起来像是一份直接为make做的工作。这样做有很多好处:增量构建、并行操作、错误检查…@bobbogo:谢谢你的评论,你有什么实际的例子可以展示/链接,让我们可以学习你的方法吗?请随意以您处理此问题的方式发布答案,这将有助于亲善学习者,我肯定会+1。感谢本速成课程。个人注意事项:
    addprefix
    通配符
    addsuffix
    是特定的语法,如果我理解正确的话
    %.b64:%
    ${targets}
    中删除
    .b64
    扩展名。对新手来说很难,而且非常有趣!是的,gnu make附带了大量函数,所有函数都是通过
    $(funcname args)
    语法访问的。
    %.b64:%
    实际上是静态模式规则的一部分,并且(在本例中)简洁地表示,当相应的
    %
    文件发生更改时,
    .b64
    文件已过期(这取决于它)。感谢本速成课程。个人注意事项:
    addprefix
    通配符
    addsuffix
    是特定的语法,如果我理解正确的话
    %.b64:%
    ${targets}
    中删除
    .b64
    扩展名。对新手来说很难,而且非常有趣!是的,gnu make附带了大量函数,所有函数都是通过
    $(funcname args)
    语法访问的。
    %.b64:%
    实际上是静态模式规则的一部分,并且(在本例中)简洁地表示,当相应的
    %
    文件发生更改时,
    .b64
    文件已过期(这取决于它)。