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