Скрытые возможности утилиты build.exe
Nov 15, 2006 · CommentsИнструменты
Не секрет, что возможности утилиты build.exe тесно завязаны на стандартное окружение, предоставляемое WDK. Это окружение формируется скриптами makefile.def, makefile.new, makefile.plt и т.д. из директории bin. Анализируя их, можно обнаружить много интересного.
Например, build.exe поддерживает макросы PASS0_PUBLISH, PASS1_PUBLISH и PASS2_PUBLISH. Пример их использования можно найти в “src\1394\dll\1394api\sources” из поставки Vista RTM WDK:
PASS0_PUBLISH=\\
{..\\..\\inc\\1394api.h=$(DRIVERS_TST_INC_PATH)\\1394api.h}
PASS1_PUBLISH=\\
{$(OBJ_PATH)\\$(O)\\1394api.lib=$(DRIVERS_TST_LIB_PATH)\\$(TARGETNAME).lib}
При сборке этой директории build.exe выдает вот следующее:
C:\\WinDDK\\5600\\src\\1394\\dll\\1394api>bcz
BUILD: Compile and Link for x86
BUILD: Start time: Wed Nov 15 21:48:36 2006
BUILD: Examining c:\\winddk\\5600\\src\\1394\\dll\\1394api directory for files to compile.
BUILD: Building generated files in c:\\winddk\\5600\\src\\1394\\dll\\1394api directory
PASS0_Pub
PASS0_Pub done
BUILD: Compiling c:\\winddk\\5600\\src\\1394\\dll\\1394api directory
Compiling - 1394api.rc
Compiling - 1394api.c
Compiling - 1394main.c
Compiling - asyncapi.c
Compiling - debug.c
Compiling - isochapi.c
Compiling - util.c
Compiling - generating code...
Building Library - objfre_wlh_x86\\i386\\1394api.lib
PASS1_Pub
PASS1_Pub done
BUILD: Linking c:\\winddk\\5600\\src\\1394\\dll\\1394api directory
Linking Executable - objfre_wlh_x86\\i386\\1394api.dll
BUILD: Finish time: Wed Nov 15 21:48:42 2006
BUILD: Done
8 files compiled
1 library built
1 executable built
Лог файл также содержит несколько интересных строк:
set BUILDMSG=PASS0_Pub
Publish not available... /O_BINARY_METADATA: -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm26D.tmp
set BUILDMSG=PASS0_Pub done
и
set BUILDMSG=PASS1_Pub
Publish not available... -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm270.tmp
set BUILDMSG=PASS1_Pub done
Поиск строки “Publish not available” сразу находит следующий код в setenv.bat:
set PUBLISH_CMD=@echo Publish not available...
В свою очередь PUBLISH_CMD упоминается в makefile.plt:
!ifndef PUBLISH_CMD
PUBLISH_CMD=perl.exe $(NTMAKEENV)\\publish.pl /Pass:$(BUILD_PASS)
!endif
Интересно. Если запустить сборку без объявления переменной PUBLISH_CMD получается вот такой результат:
set BUILDMSG=PASS0_Pub
perl.exe c:\\winddk\\5600\\bin\\publish.pl /Pass:PASS0 /O_BINARY_METADATA: -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm276.tmp
Can't open perl script "c:\\winddk\\5600\\bin\\publish.pl": No such file or directory
set BUILDMSG=PASS0_Pub done
...
set BUILDMSG=PASS1_Pub
perl.exe c:\\winddk\\5600\\bin\\publish.pl /Pass:PASS1 -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm279.tmp
Can't open perl script "c:\\winddk\\5600\\bin\\publish.pl": No such file or directory
set BUILDMSG=PASS1_Pub done
Стандартная поставка WDK не включает файл publish.pl, который, судя по всему, и выполняет полезную работу. Один параметров, передаваемых publish.pl, - имя временного файла. Чтобы посмотреть его содержимое можно воспользоваться таким командным файлом:
@echo off
if exist "%2" ( type "%2" )
if exist "%3" ( type "%3" )
В этом случае вывод выглядит вот так:
set BUILDMSG=PASS0_Pub
D:\\projects\\ShellLink\\ShellPS\\a.cmd /O_BINARY_METADATA: -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm295.tmp
{..\\..\\inc\\1394api.h=\\1394api.h}
set BUILDMSG=PASS0_Pub done
...
set BUILDMSG=PASS1_Pub
D:\\projects\\ShellLink\\ShellPS\\a.cmd -F
c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\nm298.tmp
{c:\\winddk\\5600\\src\\1394\\dll\\1394api\\objfre_wlh_x86\\i386\\1394api.lib=\\1394API.lib}
set BUILDMSG=PASS1_Pub done
Очевидно, что содержимое файла представляет собой значение соответствующего текущему проходу макроса PASSX_PUBLISH. Продолжив поиски нетрудно найти все места вызова PUBLISH_CMD в makefile.new:
PASS0_Pub: $(PASS0_OBJECTS) $(NTTARGETFILE0)
!if defined(PASS0_PUBLISH) && "$(BUILD_PASS)" != "PASS1" && "$(BUILD_PASS)" != "PASS2"
set BUILDMSG=$(@F)
$(PUBLISH_CMD) /O_BINARY_METADATA:$(_O_BINARY_METADATA) -F <<
$(PASS0_PUBLISH:}=}
)
<<$(BUILD_NOKEEP)
set BUILDMSG=$(@F) done
!endif
Какие можно сделать выводы? По всей видимости, макросы PASSX_PUBLISH используются для копирования и постобработки файлов на каждом из этапов сборки. Очевидно, что этот механизм можно использовать для выполнения каких-либо своих задач. :-) Важно только помнить, что это недокументированная возможность, которая может быть изменена или удалена в следующей версии WDK.