二次扩展和两个makefile

Secondary expansion and two makefiles

我有一个带有两个美元符号的命令(二次扩展)

$(PREFIX)/bin/gdk-pixbuf-query-loaders > $(shell $(PREFIX)/bin/gdk-pixbuf-query-loaders | awk -F "=" '/LoaderDir/ {print $}' | tr -d ' ')/../loaders.cache

shell 命令应从以下输出中提取路径:

...
# LoaderDir = /home/redux/x-libs/i686-nptl-linux-gnu/lib/gdk-pixbuf-2.0/2.10.0/loaders
...

当我 运行 make 时,规则扩展为以下命令:

/home/redux/x-libs/i686-nptl-linux-gnu/bin/gdk-pixbuf-query-loaders > /home/redux/x-libs/i686-nptl-linux-gnu/lib/gdk-pixbuf-2.0/2.10.0/loaders/../loaders.cache

没关系,但如果我使用第二个 makefile 来启动第一个 makefile,则规则会扩展为

/home/redux/x-libs/i686-nptl-linux-gnu/bin/gdk-pixbuf-query-loaders > /../loaders.cache

发生错误:

/bin/sh: 11: cannot create /../loaders.cache: Permission denied

从第二个makefile开始第一个makefile的命令如下:

$(MAKE) -f $(makefile_path)/build_libs_for_host.mk .print_and_write_triplets $(RULES) JOBS=$(JOBS) HOST=$(patsubst build_host_%,%,$@)

启动第二个 makefile(启动我创建的第一个 makefile)的命令(在 bash 中)是:

time make -f ~/_dev/_pro/second.mk all RULES=build_gdk_pixbuf JOBS=-j4 |& tee ~/log_20170221_x-libs.txt

两个 makefile 都使用 .SECONDEXPANSION:。我看不出错误。

现在我卡住了。这个扩展有什么问题?

GNU make 有一些神奇的规则,也许我必须在 $(MAKE) 行中添加一个参数?

我找到了解决办法。我的完整规则太复杂,所以我 post 简化了代码来解释我的解决方案。

首先我们有一个创建文件夹并在同一命令中使用 $(shell ...) 的规则:

all:
    mkdir -p $(PREFIX) && \
    cd $(PREFIX) && \
    cat $(PREFIX)/../$(INPUT) > $(shell cat $(PREFIX)/../$(INPUT) | awk -F "=" '/LoaderDir/ {print $}' | tr -d ' ')/./loaders.cache
    touch $@
    @echo [DONE]

如果之前没有创建文件夹,这可能会失败。在这种情况下 $(shell ...) 将扩展为一个空字符串。并且 cat 命令将失败。我们在这里看到这不是扩展问题。这是一个时间问题。

解决方案是将此规则分为两部分:

all_pass1:
    mkdir -p $(PREFIX) && \
    touch $@
    @echo [DONE]

all_pass2: all_pass1
    cd $(PREFIX) && \
    cat $(PREFIX)/../$(INPUT) > $(shell cat $(PREFIX)/../$(INPUT) | awk -F "=" '/LoaderDir/ {print $}' | tr -d ' ')/./loaders.cache
    touch $@
    @echo [DONE]

好的,我有办法。但我想知道为什么我的第一个 makefile 有效而第二个开始第一个失败。这就是我 post 解决这个问题的原因。在我看来,这仍然像是一些 GNU 魔法。

对我来说它已经解决了,但如果您认为有更好的解决方案,请随时发表评论或提出更好的解决方案。