Dynamic Makefile中依赖关系的动态评估

Dynamic Makefile中依赖关系的动态评估,dynamic,latex,makefile,Dynamic,Latex,Makefile,我正在为LaTex文档编写一个Makefile。作为makefile的一部分,我只想在相应的BIB文件更改时,或者(如果使用书目样式)在书目样式.bst文件更改时创建BBL文件 为了跟踪文件更改,我使用了MD5哈希(我在使用时间戳时遇到了问题) 我试图使用以下代码从AUX文件检索所需的BST文件: # Get the BST dependencies from an AUX file get-bibstyle = $(foreach bst, $(shell sed -n 's/\\bibsty

我正在为LaTex文档编写一个Makefile。作为makefile的一部分,我只想在相应的BIB文件更改时,或者(如果使用书目样式)在书目样式.bst文件更改时创建BBL文件

为了跟踪文件更改,我使用了MD5哈希(我在使用时间戳时遇到了问题)

我试图使用以下代码从AUX文件检索所需的BST文件:

# Get the BST dependencies from an AUX file
get-bibstyle = $(foreach bst, $(shell sed -n 's/\\bibstyle{\(.*\)}/\1/p' $1 | tr '\n' ' '), $(addsuffix .bst, $(bst)))
然后,我使用以下代码创建BBL文件:

# bbl: Bibtex produces .aux files from .aux files.
#      Also depends on .bst files (if they appear in the aux file).
%.bbl: $(call to-md5,%.aux) $(call to-md5, $(call get-bibstyle,$*.aux))
ifneq ($(strip $(BIB_SRC)),)
    $(IGNORE_RESULT)$(MUTE)$(VERBOSE) $(ECHO) "Building target: $@"
#   $(IGNORE_RESULT)$(MUTE)$(MOVE_TO_COL)
    $(IGNORE_RESULT)$(MUTE)$(SETCOLOUR_RED)
    $(IGNORE_RESULT)$(MUTE)$(ECHO) "===========================BIBTEX PASS================================"
    $(BIBTEX) $(*F)
    $(IGNORE_RESULT)$(MUTE)$(SETCOLOUR_LIGHTRED)
    $(IGNORE_RESULT)$(MUTE)$(ECHO) "===========================BIBTEX/LaTeX PASS================================"
    $(TEX) $(*F)
    $(IGNORE_RESULT)$(MUTE)$(RESTORE_COLOUR)
endif
to-md5函数只是将.md5附加到其输入
to-md5=$(patsubst%,%.md5,$1)

我希望xyz.bbl的依赖项是xyz.bib,所有bst文件都是通过在xyz.aux文件上运行sed表达式返回的。我知道这必须通过eval和call的组合来完成,但我还没有弄明白

目前,我的输出如下

sed: can't read .aux: No such file or directory
make: `xyz.bbl' is up to date.

这种方法的问题是什么

%.bbl: $(call to-md5,%.aux) $(call to-md5, $(call get-bibstyle,$*.aux))
就是说Make在构建依赖关系树之前展开了preq(也就是说,不知道
%
是什么)。因此,第一个preq,
$(调用-md5,%.aux)
变为
%.aux.md5
,这将非常好地工作,但是在第二个preq
$(调用get bibstyle,$*.aux)
失败,因为
$*
计算结果为零,并且没有要扫描的
.aux
这样的文件。(对于
%
$$*
或其他任何东西,您都会遇到同样的问题,只是名称没有提取出来。)

这是可以做到的。我能想到的最简单的方法是递归使用Make:

-include Makefile.inc

# If there's no exact rule for this target, add it to the list, note its preqs
# and start over.
%.bbl:  
    @echo KNOWN_BBL += $@ > Makefile.inc
    @echo $@: $(call to-md5,$*.aux) $(call to-md5, $(call get-bibstyle,$*.aux)) >> Makefile.inc
    @$(MAKE) -s $@

$(KNOWN_BBL):
ifneq ($(strip $(BIB_SRC)),)
    $(IGNORE_RESULT)$(MUTE)$(VERBOSE) $(ECHO) "Building target: $@ from $^"
    ...

请注意,这将为每个BBL重新运行Make,如果您想构建很多BBL,这可能不是很有效。我认为只有一种方法可以做到这一点,但这需要更多的思考…

使用时间戳时,您的问题在哪里?时间戳是否会在没有内容更改时更新?是的,这就是问题所在。
touch
可用于在没有内容更改的情况下更改文件的时间戳。但是我想知道为什么一个文件会被重建,并且与旧版本相比不会有任何变化……我很感激做这些事情是令人愉快的,但是有什么理由你不能仅仅使用
latexmk
,我想这正是你在这里想要实现的?