动态评估Makefile中的依赖项

时间:2012-05-02 07:52:29

标签: dynamic latex makefile

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

为了跟踪文件更改,我使用的是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,并通过在xyz.aux文件上运行sed表达式返回所有bst文件。我知道这必须通过eval和call的组合完成,但我无法弄明白。

目前,我的输出如下。

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

1 个答案:

答案 0 :(得分:3)

这种方法的问题

%.bbl: $(call to-md5,%.aux) $(call to-md5, $(call get-bibstyle,$*.aux))

是Make在构建依赖关系树之前扩展preqs(也就是说,不知道%是什么)。因此,第一个preq,$(call to-md5,%.aux)变为%.aux.md5,这将非常有效,但在第二个preq $(call get-bibstyle,$*.aux)失败,因为$*评估为空,并且没有.aux这样的文件1}}扫描。 (你对%$$*或其他什么都有同样的问题,这个名字就不在那里提取。)

可以做到。我能想到的最少的Rube-Goldbergian方法是使用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 ,这可能效率不高。我认为只有一种方法可以做到这一点,但需要更多的思考......