Использование nmake с подстановочными целями

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