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

  • Win7

    Поскольку концентрация упоминаний вокруг меня ещё не вышедшей ОС превысила все допустимые размеры, я решил посмотреть своими глазами на это счастие. Мне очень понравилось! В жертву была принесена машина, на которой стояла DesktopBSD, на которую я безуспешно пытался поставить KDE4. Машина, кстати, довольно древняя – Athlon 2500+, 2GB RAM, Radeon X850, 320 GB SATA HDD….

  • Как я провел выходные

    В субботу “утром” поперся на м.”Лесная”, откуда мы толпой поехали в ТРЦ “Терминал”, как оказалось кататься на картингах, ну меня обломало и мы с группкой раскольников пошли играть в боулинг – мой первый экспириенс. Игра оказалась на удивление занятной, надо будет почитать про технику кидания гадкого, тяжелого шарика по полированному полу. За час мы успели…

  • espresso test failure

    Если внезапно вы решили подключить espresso и начать писать тесты, а потом после очередных манипуляций вдруг тесты приложения перестали запускаться и начали бросать исключение NoClassDefFoundError YourActivity, то вполне вероятно, что может спасти совершенно нелогичное действие: Добавить исключения суппорт либы в gradle для компиляции espresso (в моём случае espresso-contrib) androidTestCompile (‘com.android.support.test.espresso:espresso-contrib:2.2’) { exclude group: ‘com.android.support’ exclude…

  • Сроки

    Я начинаю думать, что “уровень крутизны” зависит от того насколько поставленные сроки отличаются от реальных – чем меньше разница, тем лучше. И судя по тому, что я собирался к концу этой недели закончить плагинчик для внутреннего тестирования, но это не удалось, то расти мне ещё и расти 🙂 Share this post: Share on X (Twitter)…

  • RA

    А Electronic Arts-то теперь раздают старый добрый Red Alert бесплатно! Today, August 31st, 2008 marks the 13th anniversary of the storied Command & Conquer franchise, which has sold over 25 million copies to date. And to celebrate this milestone and this October’s highly anticipated return to the world of Red Alert with Red Alert 3,…

  • Двойные стандарты

    Интересно, почему вокруг так часто наблюдается страсть к двойным стандартам? Начиная с политики, и заканчивая соседями. Вот сгорает лампочка в корридоре – я выйду её и поменяю на свою. Но когда она сгорит в следующий раз – надо очень долго ждать, что сосед(ка) возьмёт и вкрутит свою – оно вроде бы и мелочь, а неприятно….