Вывод на печать при выполнении public01, public02, - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть следующий Makefile:

CC = gcc
CFLAGS = -ansi -Wall -g -O0 -Wwrite-strings -Wshadow \
-pedantic-errors -fstack-protector-all 
PROGS = public01 public02 public03 public04 public05 public06 shell_jr

.PHONY: all clean

all: $(PROGS)

clean:
    rm -f *.o $(PROGS) a.out

$(PROGS): shell_jr.c
public0%:
    shell_jr < public0%.in > output
    cat output

При каждом вводе public0X должен отображаться вывод shell_jr. c при запуске с вводом из public0X.in. Тег public0% - моя попытка сделать это. Однако есть 3 проблемы. Во-первых, я могу иметь только public0% .in в качестве зависимости. Этого можно избежать, скопировав отдельные команды для public01, public02, ... Во-вторых, когда я делаю это и выполняю make, команда выполняется немедленно. Как убедиться, что команда не выполняется, пока я не наберу public01 и не нажму enter?

1 Ответ

2 голосов
/ 26 апреля 2020

Во-первых, у меня может быть только public0% .in в качестве зависимости.

Я рассматриваю эту часть, как вопрос о том, как express в рецепте указать правильное имя для входной файл, соответствующий выбранной цели. % правила шаблона раскрывается только в цели и предварительных условиях, но не в рецепте, а в any make рецепте, автоматическая c переменная $@ представляет полное имя цели в процессе постройки. Поскольку требуемое входное имя формируется путем добавления суффикса .in к имени цели, оно может быть выражено как $@.in.

Кроме того, цели public0% не называются как .PHONY ( в отличие от clean и all), но ваше правило для них фактически не создает их. Если вы пытаетесь как создать, так и отобразить эти файлы, то вы также можете использовать $@, чтобы направить вывод в нужный файл. В противном случае вы также должны пометить эти цели как .PHONY.

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

Во-вторых, когда я это делаю и выполняю make, команда немедленно выполняется. Как убедиться, что команда не выполняется, пока я не наберу public01 и не нажму enter?

make не является интерактивным. Если вы хотите указать конкретную цель или цели для построения вместо значения по умолчанию, тогда вы express будете указывать их в качестве дополнительных аргументов в командной строке make:

make public01

Но я думаю, что вы ' Попытка добраться до может быть другой проблемой, чем то, что вы на самом деле сказали. Ваша цель по умолчанию создаст все цели, названные в $(PROGS), и если предварительные условия не требуют иного, GNU make, работающий в последовательном режиме, попытается построить цели в том порядке, в котором они названы. Все ваши public0% зависят от программы shell_jr, но они не определяют ее как обязательное условие. (Они делают имя shell_jr.c в качестве предварительного условия, но на самом деле это не прямая зависимость, и назначение ее как таковой не служит полезной цели.) Поэтому make попытается построить все цели public0%, прежде чем пытаться построить shell_jr.

Правильно сделать здесь - express правильные зависимости. Эта версия делает это, исходя из предположения, что public0% предназначены для фактических построенных файлов:

CC = gcc
CFLAGS = -ansi -Wall -g -O0 -Wwrite-strings -Wshadow \
    -pedantic-errors -fstack-protector-all 

PROGS = shell_jr
OUTPUTS = public01 public02 public03 public04 public05 public06

.PHONY: all clean

all: $(PROGS) $(OUTPUTS)

clean:
    rm -f *.o $(PROGS) $(OUTPUTS)

# shell_jr is built according to a built-in rule (as was already the case)

public0%: public0%.in shell_jr
    shell_jr < $@.in > $@
    cat $@

Обратите внимание, что это перестроит (и отобразит) файлы public0%, только если их соответствующие входные файлы изменились или если shell_jr необходимо было восстановить. Если вы хотите, чтобы они создавались и отображались, даже если ничего не изменилось, вы можете добавить цель без предварительных условий или рецепта и сделать ее предпосылкой для правила public0%:

public0%: public0%.in shell_jr FORCE
    shell_jr < $@.in > $@
    cat $@

FORCE:

.PHONY: FORCE

FORCE цель будет считаться восстановленной каждый раз, когда make запускается, таким образом, вызывая восстановление public0% целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...