4

我正在为 LaTex 文档编写 Makefile。作为 makefile 的一部分,我只想在相应的 BIB 文件更改或(如果使用参考书目样式)bibliographystyle.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 并且通过在 xyz.aux 文件上运行 sed 表达式返回所有 bst 文件。我知道这必须通过 eval 和 call 的组合来完成,但我无法弄清楚。

目前,我的输出如下。

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

1 回答 1

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可以扫描。(你会遇到同样的问题%$$*或者其他什么,名称只是不存在提取。)

可以办到。我能想到的最少的 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,这可能不是很有效。我认为有一种方法可以只执行一次,但这需要更多的思考......

于 2012-05-02T15:04:10.907 回答