Скрытые возможности утилиты build.exe

Не секрет, что возможности утилиты 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.

comments powered by Disqus