0

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

$(PREFIX)/bin/gdk-pixbuf-query-loaders > $(shell $(PREFIX)/bin/gdk-pixbuf-query-loaders | awk -F "=" '/LoaderDir/ {print $$2}' | 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 来启动第一个,那么规则将扩展为

/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)在行中添加一个参数?

4

1 回答 1

0

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

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

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

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

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

于 2017-02-21T16:44:05.460 回答