#makefile #nmake
#makefile #nmake
Вопрос:
Используя nmake
, у меня есть следующий makefile, который в настоящее время выполняет то, что мне нужно. mycmd
(запускаемая программа) возьмет .inp
файл и создаст .out
файл. Я могу создавать столько .inp
файлов, сколько мне нужно, и makefile не должен меняться. Он найдет их все и создаст все соответствующие .out
файлы.
#####################################################################################
# A SUFFIXES declaration is required in order to later use the rule with target .inp.out
#####################################################################################
.SUFFIXES: .inp
#####################################################################################
# Here, NMAKE will expand *.inp in the prereq list for all, into the list of *.inp
# files in the directory, and then it will start a new NMAKE instance, specifying the
# goals to build all those files.
#####################################################################################
all: *.inp
$(MAKE) $(**:.inp=.out)
#####################################################################################
# $(*B) represents the current target's base name minus the path and the file extension
#####################################################################################
.inp.out:
mycmd -i $(*B).inp -o $(*B).out
Мой вопрос в том, как мне еще больше улучшить этот makefile, чтобы я мог, например, запускать его для набора .inp
файлов, так что *.inp
, кроме как сказать, ABC*.inp
?
Ответ №1:
Простая модификация вашего makefile должна работать. Добавьте новый $(pattern)
макрос:
.SUFFIXES: .inp
pattern = * # new macro; defaults to *
all: $(pattern).inp # use it!
@$(MAKE) -nologo $(**:.inp=.out)
.inp.out: # dummy stub for testing
@echo mycmd -i $(*B).inp -o $(*B).out
@type NUL > $(*B).out
Затем в командной строке перезапишите pattern
. Например, nmake -nologo pattern=ABC*
.
Обновление: командная строка в вашем makefile:
$(MAKE) $(**:.inp=.out)
завершится ошибкой fatal error U1095: expanded command line
… too long
если строка $**
слишком длинная. В моей системе это происходит примерно на 32800 символов.
Добавление восклицательного знака !
в начало (см. Здесь ), похоже, не работает, вероятно, потому, что нет простого $**
. Необходимо использовать два обходных пути:
!call set a=$** amp; call nmake %%a:.inp=.out%%
или:
!for %a in ($**) do nmake -nologo %~na.out
Оба они примерно в два раза медленнее, чем ваш оригинал, с mycmd
заглушкой, которая ничего не делает. ( for
Цикл здесь на самом деле не цикл, потому $**
что это всего лишь один элемент.)
Комментарии:
1. Редактировать: возможно, упомянуть en.wikipedia.org/wiki /. …
2. Спасибо! и Хар хар во втором комментарии : -D
3. Спасибо за обновление. Моему makefile не нужно обрабатывать файлы размером около 32 Тыс. символов, поэтому это ограничение для меня не проблема (кто бы делал имена файлов такими длинными !?)
Ответ №2:
Другое решение — сохранить исходный makefile и использовать команду DOS, такую как:
for %a in (ABC*.inp) do nmake -nologo %~na.out
Здесь синтаксис %~na
удаляет расширение из переменной %a
.
Это немного медленнее, чем просто использование makefile, но ненамного. Например, с 600 inp
файлами и mycmd
заглушкой в моей системе эта команда занимает 20 секунд по сравнению с 15 секундами для makefile.