Вторичное расширение и два make-файла

У меня есть команда с двумя знаками доллара (вторичное расширение)

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

Команда оболочки должна извлечь путь из следующего вывода:

...
# 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

Это нормально, но если я использую второй make-файл, который запускает первый, то правило расширяется до

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

и возникает ошибка:

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

Команда для запуска первого make-файла из второго make-файла выглядит следующим образом:

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

И команда (в bash) для запуска второго make-файла (который запускает первый, который я создал):

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

Оба make-файла используют .SECONDEXPANSION:. Я не вижу ошибки.

Теперь я застрял. Что не так с этим расширением?

В GNU make есть волшебные правила, и, может быть, мне нужно добавить параметр в строку $(MAKE)?


person B. A. Sylla    schedule 21.02.2017    source источник
comment
Рекурсивный мейк? Звучит забавно.   -  person melpomene    schedule 21.02.2017
comment
,SECONDEXPANSION относится только к оценке предпосылок правил; это абсолютно не влияет на содержание рецептов. Учитывая информацию здесь, мы не можем вам помочь, есть что-то еще, о чем вы нам не сказали. Я рекомендую запускать отдельные команды и распечатывать их вывод, чтобы увидеть, в чем разница. Возможно, одна из переменных, добавленных вами в командную строку, меняет поведение gdk-pixbuf-query-loaders. Добавьте $(info $(shell $(PREFIX)/bin/gdk-pixbuf-query-loaders)) и сравните два способа вызова make.   -  person MadScientist    schedule 21.02.2017


Ответы (1)


Я нашел решение. Мое полное правило слишком сложное, поэтому я публикую упрощенный код, чтобы объяснить свое решение.

Сначала у нас есть правило, которое создает папку и использует $(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]

Хорошо, у меня есть решение. Но мне интересно, почему мой первый make-файл работал, а второй, запустивший первый, терпит неудачу. И именно поэтому я опубликовал эту проблему. Мне все еще кажется, что это какая-то магия GNU.

Для меня это решено, но не стесняйтесь комментировать или предлагать лучшее решение, если вы считаете, что есть лучшее.

person B. A. Sylla    schedule 21.02.2017