Makefile 检测生成命令目标是路径还是伪路径 背景
我正在写几本降价书。我的文件结构如下:Makefile 检测生成命令目标是路径还是伪路径 背景,makefile,Makefile,我正在写几本降价书。我的文件结构如下: Description writing/ Makefile 1. main Makefile (shown below) book.template 2. pandoc template that uses TITLE books/ current.txt
Description
writing/
Makefile 1. main Makefile (shown below)
book.template 2. pandoc template that uses TITLE
books/
current.txt 3. contains the current book name
book1/
meta.mk 4. sub-Makefile that defines TITLE
chapters/
01.md 5. actual text of book 1, chapter 1
02.md
...
book2/
meta.mk
chapters/
01.md
02.md
...
...
以下是生成文件:
CURR_BOOK_NAME:=$(shell cat books/current.txt)
CURR_BOOK_DIR:=books/$(CURR_BOOK_NAME)/
CURR_CHAPTERS_DIR:=$(CURR_BOOK_DIR)chapters/
CURR_CHAPTERS:=$(wildcard $(CURR_CHAPTERS_DIR)*.pdf)
# suppose that each meta.mk defines the TITLE variable
include $(CURR_BOOK_DIR)/meta.mk
all: pdfs
...
pdfs: $(CURR_CHAPTERS)
%.pdf: %.md book.template
pandoc -o $@ $< ... \
--template=book.template \
--variable=title:$(TITLE)
可能的解决方案
建议重写命令行上的变量:
make CURR_BOOK_NAME=book2 books/book2/chapters/01.pdf
但是,我认为这太冗长和多余了,因为它需要重复两次书的名称,并键入一次内部变量的名称CURR\u book\u name
注
这是一个简化的例子。请询问是否要查看实际的Makefile。另外,请随时澄清问题标题。以下有价值的答案已在早些时候发布,但在简短讨论了评论中的赞成/反对意见后,回答者删除了它,并在没有选择评论的情况下投了反对票。我把它放在这里,以防它帮助其他用户。我仍然在寻找一个“更复杂”的解决方案,它可以避免冗余并允许构建单独的章节
一个简单的解决方案是将
Makefile
复制到一个新文件,比如book.mak
,然后删除第一行CURR\u book\u NAME:=$(shell cat books/current.txt)
。然后创建新的Makefile,如下所示:
CURR_BOOK_NAME:=$(shell cat books/current.txt)
current:
$(MAKE) -f book.mak CURR_BOOK_NAME="$(CURR_BOOK_NAME)"
book1:
$(MAKE) -f book.mak CURR_BOOK_NAME="book1"
book2:
$(MAKE) -f book.mak CURR_BOOK_NAME="book2"
然后,当您在book1中更改某些内容而book2为当前时,只需键入makebook1
。makefile将找出更改的内容并进行更新
如果您真的希望能够键入
makebooks/book2/chapters/01.pdf
,那么它就有点复杂了。我会重新构造它,以便从每个项目的顶级目录中引用顶级Makefile。将其视为每个图书项目的支持库,并对其进行相应的管理
然后,单个Makefile就可以像
include /usr/local/share/lib/bookmaker/main.mk
。。。假设您调用库bookmaker
,并将其安装在此路径。(它也可以存在于主目录下的某个树上。)
我会认为这是一个正常化的事实上的项目结构,而不是一个新的安排。您的个人书籍已经依赖于BookMakefile,但强制它们位于物理子目录中会使实验性克隆变得更加困难(假设您将每本书作为单独的Git项目进行管理——如果不是,那么切换到此模型可能更有意义!)。您还可以摆脱“当前”状态文件带来的微小但烦人的不便,您现在显然不再需要这些文件。谢谢您的回答。不幸的是,从一小时前开始,我就没法投票了。我想我不愿意在每个图书目录中创建一行makefile,因为它看起来是多余的。我试图解析
$(MAKECMDGOALS)
。这种安排还允许您摆脱meta.mk
,因为它现在可以重构到本书的主Makefile中;因此,每个目录中已经有一行文件。但这一点更一般(当然,元文件也可以定义其他目标或覆盖主Makefile中的规则,尽管更加模糊)。
include /usr/local/share/lib/bookmaker/main.mk