2013-12-16 2 views
1

Я написал следующее Makefile:переопределение Makefile переменная в зависимости от типа сделать

INTERACTION=nonstopmode 

all: 
    make read.pdf > /dev/null 
    make clean > /dev/null 
diagnostic: 
    INTERACTION=batchmode 
    make read.pdf 
    make clean 
%.pdf: %.tex biblio.bib 
    bash makepdf.sh $(INTERACTION) $< 
clean: 
    rm -f *.aux *.log *.bbl *.bak *.blg *.toc *.out *.glg *.glo *.gls *.ist *~ *.*~* *.backup 

Makefile обеспечивает два режима: простой грим файл, который не делает вывода об ошибках и предупреждения и диагностики так что pdflatex взаимодействует с пользователем, чтобы найти проблему.

makepdf.sh выглядит следующим образом:

filename=$(basename $2) 
filename="${filename%.*}" 
pdflatex -interaction=$1 $2 
makeglossaries "$filename" 2 
makeindex "$filename" 2 
pdflatex -interaction=$1 $2 
echo $1 

Независимо от того, является ли называется make или make diagnostic, программа всегда работает в nonstopmode. Невозможно перезаписать переменную Makefile? Если да, то как решить эту проблему? В противном случае, что не так с этим кодом?

ответ

2

Этот файл makefile довольно странный. В принципе, не написано правильно.

Самый прямой ответ на ваш вопрос заключается в том, чтобы вы поняли, что каждая строка рецепта make-файла вызывается в отдельной оболочке, а в системах UNIX/POSIX процесс не может влиять на среду его родителя. Это означает, что изменения, внесенные в среду в оболочке, вызывающей вызовы, не влияют на процесс make или на любые последующие оболочки. Таким образом, INTERACTION=batchmode запускается в оболочке и устанавливает переменную INTERACTION в batchmode, тогда оболочка выходит и эта настройка забыта, затем следующая строка запускается с предыдущей настройкой. Если вы хотите, чтобы переменные вступили в силу, вы должны поместить их в одну и ту же логическую строку в рецепте.

Однако в этом файле makefile есть еще более фундаментальные проблемы. Во-первых, вы должны никогда запустите make, чтобы вызвать рекурсивный make. Всегда используйте переменную $(MAKE).

Во-вторых, вы не должны запускать вспомогательные устройства в любом случае. Вся цель перечисления предварительных условий в make-файле заключается в том, чтобы принудительно выполнить заказ при вызове правил; здесь вы пытаетесь взять на себя работу make, выполнив команды рекурсивно.

В-третьих, если вы используете GNU, вы можете использовать целевые переменные для того, что вы хотите сделать намного проще (см. Руководство GNU make). Например ваш Makefile может быть более правильно написано, как это (примечание, не рекурсии на всех!):

INTERACTION = nonstopmode 

all: read.pdf 

diagnostic: INTERACTION = batchmode 
diagnostic: all 

%.pdf: %.tex biblio.bib 
     bash makepdf.sh $(INTERACTION) $< 

clean: 
     rm -f *.aux *.log *.bbl *.bak *.blg *.toc *.out *.glg *.glo *.gls *.ist *~ *.*~* *.backup 

Это не запускается clean правила автоматически после каждой сборки.

Смежные вопросы