Коварные скобки или цена ошибок в дизайне
Nov 29, 2006 · CommentsДизайнИнструментыWow64
Пару недель назад столкнулся с проблемой, пытаясь собрать 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)” явно не был учтён тот факт, что скобки входят в список специальных символов командного интерпретатора. В результате эта ошибка даёт о себе знать в самых неожиданных местах, вроде описанного выше.