Коварные скобки или цена ошибок в дизайне

Пару недель назад столкнулся с проблемой, пытаясь собрать 64-х битную версию Boost.Jam из поставки Boost.Build. Скрипт build.bat, запускающий процесс сборки, выдавал не очень понятное сообщение “\Microsoft was unexpected at this time.”:

Включение эха, чтобы были видны выполняемые команды, полностью ситуацию не прояснило:

Впрочем, последняя команда, присваивающая значение переменной BOOST_JAM_TOOLSET_ROOT, выглядит более чем подозрительно. Во-первых, в выводе присутствует часть сообщения об ошибке - “\Microsoft”. Во-вторых, там же упоминается “Program Files (x86)”, а это практически наверняка указывает на проблемы совместимости с Wow64 окружением.

Чтобы проверить эту догадку, я скопировал эту команду в отдельный .bat файл. Интересно, что в этом случае всё работало как часы:

Покопавшись еще немного, я вспомнил, что команда “IF” всегда выполняется как одна команда, даже если она содержит несколько других команд. Проблемный “SET” как раз был заключен в “IF”.

if NOT "_%VS80COMNTOOLS%_" == "__" (
    set BOOST_JAM_TOOLSET=vc8
    set BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\\..\\VC\\
    goto :eof)

Скопировав “IF” целиком, я получил то же самое сообщение об ошибке:

Скорее всего, причина ошибки была в круглых скобках в “Program Files (x86)”. Изменив значение VS80COMNTOOLS на “C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\” я убедился, что это так:

В конце концов, выяснилось, что парсер команд неверно обрабатывает закрывающую скобку как закрывающую список команд после “IF” или “ELSE”. При всем при этом вложенные “IF” отрабатывались нормально. Видимо, в качестве открывающей скобки выступает весь “IF”, включая условие и открывающую скобку.

Пока что я не нашел удобного решения данной проблемы. Возможно, здесь поможет отложенное раскрытие переменных: “SETLOCAL ENABLEDELAYEDEXPANSION” или опция /V:ON при запуске cmd.exe. В моём же случае, я просто определил необходимые переменные вручную.

И кстати о названии данного поста. Подобная проблема – типичный пример ошибки в дизайне. При выборе имени “Program Files (x86)” явно не был учтён тот факт, что скобки входят в список специальных символов командного интерпретатора. В результате эта ошибка даёт о себе знать в самых неожиданных местах, вроде описанного выше.

comments powered by Disqus