我正在为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.
答案 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 ,这可能效率不高。我认为只有一种方法可以做到这一点,但需要更多的思考......