У меня есть Makefile, где одна цель зависит от нескольких файлов - каждая из которых должна обрабатываться отдельно (без предоставления промежуточных выходных файлов). Мой конкретный сценарий более сложный:Как подать несколько файлов на фоновый процесс с помощью Makefile
У меня есть источник C, из которого я хотел бы извлечь определения перечислений. Есть несколько морщин, которые я не могу изменить:
- Компилятор не GCC - это настраиваемый компилятор от Cosmic Software.
- В дополнение к компилятору я могу запустить анализатор (давайте назовем его parser.exe) сам по себе, и у него есть опция (
-e
) для вывода предварительно обработанного источника на STDOUT. - make на самом деле является проприетарной версией, которая поставляется с программным пакетом PTC Integrity. Он не поддерживает циклы - если я хочу использовать циклы, мне придется делать пакетные скрипты Windows.
- Это все работает на Windows,
Я написал утилиту (с помощью C# и ANTLR), давайте назовем его ExtractEnums.exe, который извлекает перечислений (и вычисляет выражения) от источника С тех пор, как источник был предварительно обработан. Предварительно обработанный источник в целом весит чуть более 30 МБ. Вместо того, чтобы писать предварительно обработанный источник на диск с помощью анализатора Cosmic, я решил связать его с ExtractEnums.exe. Поскольку мне нужно вызвать синтаксический анализатор для каждого исходного файла, мне нужно использовать именованный канал, а не только оператор pipe (|
). В Windows названные каналы не получают реальных имен файлов, поэтому вы увидите ExtractEnums.exe -client
для записи в трубу и фоновый процесс ExtractEnums.exe -server
, который читается из трубы в приведенном ниже примере.
############################################################################
# Dummy files - these will never exist
#
D_FILES = $(SRCS:.c=.dummy) # All dummy files
server :
cmd /c start /B ExtractEnums.exe -server > temp.pipe
%.dummy : %.c server
cmd /c parser.exe $(DEFINES_AND_OPTS) -e $^ | cmd /c ExtractEnums.exe -client
# Extract enums from all the preprocessed source:
%.enums : $(D_FILES)
cmd /c echo ;;exit;; | cmd /c ExtractEnums.exe -client
cmd /c move temp.pipe [email protected]
Это все работает, если я звоню make product_name.enums
. SRCS
- это список всех исходных файлов. ;;exit;;
- это специальная строка, которую я отправляю на адрес ExtractEnums.exe -server
, чтобы сообщить об этом для выхода. Вот проблема:
Чтобы перебрать все источники и передать их в препроцессор, я составил список .dummy
файлов, которые никогда не будут существовать. Поскольку они никогда не существуют, цели всегда устарели. Это означает, что вызов make product_name.enums
всегда будет запускать все источники через препроцессор, даже если источники не изменились.
Я понимаю, что придумал сложное решение. Если у вас есть гораздо более простой способ решить эту проблему, я открыт для предложений - в этом случае я отредактирую имя этого вопроса, чтобы оно было подходящим.
Ваше описание проблемы 2 неясно. Получатель (запущенный по правилу 'server') направляет вывод в' product_name.pipe', а правило '% .enums' переименовывает этот файл в другое. В чем проблема? – Beta
Вы можете уменьшить все до одной цели '% .enums', используя периодические циклы, когда вы укажете в своем вопросе. Любая причина не делать этого? – perencia
@ Бета - Наверное, ты прав. product_name.pipe - это всего лишь временный файл. Я отредактирую свой вопрос, чтобы было ясно, что это временный файл и удалить элемент # 1. – watkipet