Makefile GNU从单个依赖项生成许多输出文件,这些文件可能与其他依赖项匹配

Makefile GNU从单个依赖项生成许多输出文件,这些文件可能与其他依赖项匹配,makefile,gnu-make,Makefile,Gnu Make,我试图寻找这个问题的答案,所以如果这是我没有找到的问题的重复,我提前道歉。也很抱歉,我不能直接提供我正在使用的代码(无论如何,这需要很多环境依赖性) 我有一系列的行动,这些行动都取决于之前行动的成功,也不需要重复,除非它们过时了。一个make解决方案似乎是合适的。我想出了一个解决方案,几乎可以解决所有问题。下面是我尝试复制的步骤序列,每个步骤的输出列在其输入下面: 压缩文件 提取到包/ package/directory/*.comp 执行uncomp.py从.comp文件创建.unco

我试图寻找这个问题的答案,所以如果这是我没有找到的问题的重复,我提前道歉。也很抱歉,我不能直接提供我正在使用的代码(无论如何,这需要很多环境依赖性)

我有一系列的行动,这些行动都取决于之前行动的成功,也不需要重复,除非它们过时了。一个
make
解决方案似乎是合适的。我想出了一个解决方案,几乎可以解决所有问题。下面是我尝试复制的步骤序列,每个步骤的输出列在其输入下面:

  • 压缩文件
    • 提取到
      包/
  • package/directory/*.comp
    • 执行
      uncomp.py
      .comp
      文件创建
      .uncomp
      文件
  • 到目前为止,一切正常
  • package/directory/*.unc
    • 对于
      *.uncomp
      文件,执行
      script1
      生成
      .html
      文件
    • 对于
      *\u ext.uncomp
      文件,执行
      script2
      生成编号的
      *\u ext.##.png
      文件
      • 多个编号文件(
        \u ext.0.png
        \u ext.1.png
        \u ext.2.png
        )是可能的,并且在运行
        make
        时可能不存在。但是,
        make
        应该知道它们是上一步的输出,并且只有当这些文件(a)不存在或(b)任何文件比
        *\u ext.unc
        文件旧时,才运行此配方
我已经创建了一个Makefile,它几乎完成了我想要的功能,只是它将最后一部分(编号文件)都委托给了一个shell脚本,我可以编写该脚本来查看文件时间,但在我看来,这首先违背了使用
make
的目的

环境 Debian 8.8(x86)

我的问题 我可以使用哪些规则和配方来通知GNU make
*\u ext.uncomp
文件和
\u ext.\35;##.png
文件之间的关系,以便仅在必要时执行这些配方(如果所有
.png
文件至少与
\u ext.uncomp
文件一样新,则说“目标是最新的”),这不适用于
*.uncomp
文件,如果输出中没有
.png
文件,这仍然有效

我还需要指出非
\u ext
文件与其对应的HTML文件之间的关系。因此,只有当HTML文件过期或不存在时,才会执行
script1
。此配方/规则不应注意
\u ext.uncomp
文件

如果您对我的Makefile有任何其他建议,我将不胜感激,因为我对它不太熟悉

我当前
Makefile的一般化内容

我学习了很多关于GNU
make
的知识,试图让它工作起来。我发现解决我问题的办法是不要想得太多

最重要的一点是,我不需要
make
来跟踪所有编号的输出文件,只需要跟踪第一个文件(如果第一个文件过期或丢失,它们都会过期,并且它们都会被脚本重新提取,因此我只需要在那里指出1:1的关系)

我发现GNU
make
3.82和更高版本在匹配模式规则时使用“最短茎优先”顺序而不是定义顺序。为了使我的文件与这两个版本兼容,我确保首先定义最具体的词干

在那之后,就是建立一些隐式规则的问题,仅仅告诉
make
能够找到这个概念的期望是什么,这与我的思维方式有点背道而驰,这就是为什么我一开始遇到一些麻烦的原因(寻找这个还不存在的文件;现在,有一种方法可以从一个确实存在的文件中创建它)。最终结果是,功能全面:

PACKAGE      := package
COMP         := .comp
UNCOMP       := .comp.uncomp
PNG0         := .comp.0.png
TXT          := .comp.txt
SUFFIX       := _ext

COMPFILES     = $(wildcard $(PACKAGE)/subdir/*$(COMP))
UNCOMPFILES   = $(COMPFILES:$(COMP)=$(UNCOMP))
SUFFIXFILES   = $(filter %$(SUFFIX)$(UNCOMP),$(UNCOMPFILES))
PNGFILES      = $(SUFFIXFILES:$(UNCOMP)=$(PNG0))
NOSUFFIXFILES = $(filter-out %$(SUFFIX)$(UNCOMP),$(UNCOMPFILES))
TXTFILES      = $(NOSUFFIXFILES:$(UNCOMP)=$(TXT))

.PHONY : all
all : pngs txts htaccess

.PHONY : txts
txts : $(TXTFILES)

.PHONY : pngs
pngs : $(PNGFILES)

.PHONY : uncomp
uncomp : $(UNCOMPFILES)
    make pngs
    make txts

.PHONY : htaccess
htaccess : $(PACKAGE)/.htaccess

%$(SUFFIX)$(PNG0) : %$(SUFFIX)$(UNCOMP)
    @# Ignore failures when extracting PNG files
    -python script1.py $<

%$(TXT) : %$(UNCOMP)
    @# Ignore failures when dumping TXT files
    -python script2.py $< > $@

%$(UNCOMP) : %$(COMP)
    @# Ignore decompression failure
    -python uncomp.py $<

$(PACKAGE)/.htaccess : .htaccess | $(PACKAGE)
    cp .htaccess $(PACKAGE)/

$(PACKAGE) : *.zip
    rm -rf $(PACKAGE)/
    unzip *.zip -d $(PACKAGE)/
    make uncomp

.PHONY : clean
clean :
    rm -rf $(PACKAGE)/
PACKAGE:=PACKAGE
组件:=.COMP
解压缩:=.comp.UNCOMP
PNG0:=.comp.0.png
TXT:=.comp.TXT
后缀:=\u ext
COMPFILES=$(通配符$(包)/subdir/*$(COMP))
UNCOMPFILES=$(COMPFILES:$(COMP)=$(UNCOMP))
后缀文件=$(过滤器%$(后缀)$(解压缩),$(解压缩文件))
PNGFILES=$(后缀文件:$(解压)=$(PNG0))
NOSUFFIXFILES=$(过滤掉%$(后缀)$(未压缩),$(未压缩文件))
TXTFILES=$(NOSUFFIXFILES:$(UNCOMP)=$(TXT))
冒牌货:全部
全部:pngs txts htaccess
.冒牌货:txts
txts:$(TXTFILES)
.冒牌货:pngs
PNG:$(PNG文件)
.冒牌货:UNPC
解压缩:$(解压缩文件)
制作PNG
制作TXT
.冒牌货:htaccess
htaccess:$(软件包)/.htaccess
%$(后缀)$(PNG0):%$(后缀)$(未压缩)
@#提取PNG文件时忽略失败
-python脚本1.py$<
%$(TXT):%%$(未压缩)
@#转储TXT文件时忽略失败
-python脚本2.py$<>$@
%$(未压缩):%%$(压缩)
@#忽略减压失败
-python解压$<
$(包)/.htaccess:.htaccess |$(包)
cp.htaccess$(软件包)/
$(套餐):*.zip
rm-rf$(套餐)/
解压*.zip-d$(软件包)/
使不匹配
.假冒:干净
清洁:
rm-rf$(套餐)/
我认为先决条件可能会对您有所帮助。
.PHONY : all
all : package package/directory/*.uncomp
    ./process $^

%.comp.uncomp : %.comp package
    python uncomp.py $<

package : *.zip
    rm -rf package/
    unzip *.zip -d package/
#!/bin/bash

if [ $# -lt 2 ]; then
    echo "$0 expects at least 2 arguments"
    exit 1
fi

# Discard the first agrument, it's always 'package'
shift

# Iterate over each of the remaining arguments
while [ $# -gt 0 ]; do
    if [[ $1 == *_ext.uncomp ]] ; then
        python script2 $1
    elif [[ $1 == *.uncomp ]] ; then
        python script1 $1
    else
        echo "Warning: Unknown file type: $1"
    fi
    shift
done
PACKAGE      := package
COMP         := .comp
UNCOMP       := .comp.uncomp
PNG0         := .comp.0.png
TXT          := .comp.txt
SUFFIX       := _ext

COMPFILES     = $(wildcard $(PACKAGE)/subdir/*$(COMP))
UNCOMPFILES   = $(COMPFILES:$(COMP)=$(UNCOMP))
SUFFIXFILES   = $(filter %$(SUFFIX)$(UNCOMP),$(UNCOMPFILES))
PNGFILES      = $(SUFFIXFILES:$(UNCOMP)=$(PNG0))
NOSUFFIXFILES = $(filter-out %$(SUFFIX)$(UNCOMP),$(UNCOMPFILES))
TXTFILES      = $(NOSUFFIXFILES:$(UNCOMP)=$(TXT))

.PHONY : all
all : pngs txts htaccess

.PHONY : txts
txts : $(TXTFILES)

.PHONY : pngs
pngs : $(PNGFILES)

.PHONY : uncomp
uncomp : $(UNCOMPFILES)
    make pngs
    make txts

.PHONY : htaccess
htaccess : $(PACKAGE)/.htaccess

%$(SUFFIX)$(PNG0) : %$(SUFFIX)$(UNCOMP)
    @# Ignore failures when extracting PNG files
    -python script1.py $<

%$(TXT) : %$(UNCOMP)
    @# Ignore failures when dumping TXT files
    -python script2.py $< > $@

%$(UNCOMP) : %$(COMP)
    @# Ignore decompression failure
    -python uncomp.py $<

$(PACKAGE)/.htaccess : .htaccess | $(PACKAGE)
    cp .htaccess $(PACKAGE)/

$(PACKAGE) : *.zip
    rm -rf $(PACKAGE)/
    unzip *.zip -d $(PACKAGE)/
    make uncomp

.PHONY : clean
clean :
    rm -rf $(PACKAGE)/