Not a kernel guy

… in the Windows kernel team

Wednesday, November 15, 2006

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

Posted at 11:33 pm •

RSS feed | Trackback URI

Comments »

No comments yet.

Your Comment (smaller | larger)

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress