MsBuild покорён

Наконец-то я разобрался с самой ужасной и неприятной особенностью msbuild – регулярное удаление промежуточного выхода компилятора, то бишь объектников.
Проблема, собсно заключалась в следующем:

При сборке, а точнее в самом её конце, перед PostBuildEvent, выполняется таск IncrementalClean, суть которого заключается в том, чтобы удалить все файлы, которые не были произведены текущей сборкой. Задумка простая и очень хорошая, таким образом мы решаем проблему того, что файл поудалял или переименовал файлы в проекте, а вот реализация, как всегда, подкачала.
Выглядит это приблизительно так:
Мы начинаем сборку, у нас компилируются исходники, получаются объектники, потом линковка и вуаля – исполняемый файл – все счастливы. Но оно заканчивается на второй сборке – очень умный msbuild видит, что файлы не менялись, поэтому компиляцию и линковку пропускает и вот тут-то нас и ждёт коварный IncrementalClean – он удаляет obj файлы, которые мы получили на прошлой сборке. Ещё он должен удалять и исполняемый файл, но этого, замечу, не делает.
Поиски по форумам и задавание вопросов специалистам из microsoft успехом не увенчались, поэтому пришлось копаться в потрохах msbuild и его сборочных скриптов. Попытки переопределить метод IncrementalClean успехом не увенчались, т.к. перестал даже простой clean работать. В конце-концов я попытался до конца разобраться, почему не удалялся исполняемый файл, ведь линковка тоже пропускалась. Оказалось, потому что переменная, в которой я хранил имя OutputName было magic. У msbuild есть волшебный таск, _CheckForCompileOutput, который проверяет существует ли “выход” компилятора, и если да, то пишет его в тот самый файл, по которому потом производится очистка, или не очистка. Но он, сцуко, работает только с одиночными файлами на входе (не забываем, что эта ацкая система ориентирована на .NET и С# в частности), а у сишарпа компилятор и линкер в одном лице работают. Попытки использовать какое-нить ещё резервированное имя не увенчались успехом.
Сегодня на меня снизошло озарение – почему бы не сделать _CheckForGccCompileOutput, после копи-паста, понятное дело, оно не заработало, но зато стало ясно, что идея очень даже сможет жить, после некоторых мучений и ковыряний, я, таки, сумел заставить его работать. Ура.

Вот, собсно, этот ацкий таргет:


<Target
Name=”_CheckForGccCompileOutputs”
>
<CreateItem Include=”@(Compile->’$(IntermediateOutputPath)%(filename).o’)”>
<Output
TaskParameter=”Include”
ItemName=”ObjFileList”
/>
</CreateItem>
<!–Record the main compile outputs.–>
<CreateItem Include=”%(ObjFileList.Identity)” Condition=”Exists(%(ObjFileList.Identity))”>
<Output TaskParameter=”Include” ItemName=”FileWrites”/>
</CreateItem>
</Target>

Поясню детальней: первая фаза создаёт новый массив, в котором содержатся имена obj файлов, вторая, собсно, по ним проходится и вносит их в магический массив FileWrites, по которому, в дальнейшем и будет проводиться анализ – что нужно удалять, а что нет.

Similar Posts

  • Отчёт. День первый: дорога

    Впечатлений за отпуск накопилось море, поэтому буду выдавать по мере переработки мозгом 🙂 Заодно запихивать под кат, т.к. букв много и не всем, наверно, интересно. Share this post: Share on X (Twitter) Share on Facebook Share on LinkedIn Share on Email Share on Reddit

  • Предвестник транспортного коллапса

    Сегодня утром я выехал из своего двора и офигел – машин на дороге было, как на каком-нить крещатике. Еле втиснулся. Дальше хуже – обнаружив, что в какой выезд с моего любимого района не ткнись – везде куча машин. Забрал Серёгу и поехали по самой короткой дороге. В результате только с троещины выезжали полтора часа –…

  • Мои выходные

    Блин, на выходные было столько разных идей – съездить на дачу, съездить в деревню, сходить на пляж, в кено или еще куда. В результате всю субботу и часть воскресенья проторчал на работе. Оставшуюся часть выходных провел за оверклокингом. Гонял процессор и свежеприобретенную видеокарточку. Водяное охлаждение рулит 🙂 Share this post: Share on X (Twitter) Share…

  • 3G Модем GOBI 2000 в Украине

    Новый ноутбук меня обрадовал скоростью, но ещё больше порадовал наличием слота для модема и подготовленной антенной, а также уже Я начал изучать eBay на предмет подходящей мне железке и увидел дивного зверя – Qualcomm Gobi-2000: модем, умеющий и CDMA (EV-DO) и GSM (UMTS). Вся сила в прошивках, которые загружаются при старте – нужен один стандарт,…

  • Новое путешествие

    Завтра 11 июля 2008 года отправляюсь в новое путешествие. Собираемся в Турцию на машине, ехать будем через Европу. За 16 дней планируем посетить в Румынии то, что не успели в первый раз, посмотреть на Болгарию и объездить саму Турцию. Надеюсь, что, несмотря на жару всё будет хорошо 🙂 Share this post: Share on X (Twitter)…

  • Про конвенцию и права

    Поднялся у нас хай, главный министр по водительским делам начал рассказывать, что оказывается у нас в 2011 году будет новая конвенция о дорожном движении от 1968 года. И по ней, права должны обязательно иметь срок годности, если за границу захочется поехать. Получать новые права как-то не охота – денег тратить, да и могут какие-нить экзамены под шумок придумать – тоже возня лишняя.

    Как оказалось – фигня это всё, и вот почему.