Почему MSBuild требует явной установки целевой платформы? - PullRequest
3 голосов
/ 01 сентября 2010

Для моего простого проекта сборка выпуска в Visual Studio производит сборку размером 18 944 байта. Но если я собираю то же решение из командной строки с MSBuild, я получаю сборку размером 28 672 байта. Это разница в 9 728 байт.

Я вызываю MSBuild с:

msbuild /p:Configuration=Release /t:Rebuild MySolution.sln

В ILDasm я видел только незначительные различия в метаданных. Сброс и сравнение дерева не показывает различий. Сброс и сравнение заголовков дали подсказку:

Visual Studio Output                             MSBuild Output
// Size of init.data:              0x00000800    // Size of init.data:              0x00002000
// Size of headers:                0x00000200    // Size of headers:                0x00001000
// File alignment:                 0x00000200    // File alignment:                 0x00001000

Разница в размере данных инициализации составляет 0x1800 или 6,144 байта. Разница в размере заголовка составляет 0xE00 или 3584 байта. Сумма этих двух различий составляет 9 728 байт, что объясняет расхождение. Разница в выравнивании файла составляет 3584 байта.

Дальше я вижу:

Visual Studio Output                                    MSBuild Output
// File size            : 18944                         // File size            : 28672
// PE header size       : 512 (496 used)    ( 2.70%)    // PE header size       : 4096 (496 used)    (14.29%)
// Data                 : 2048              (10.81%)    // Data                 : 8192              (28.57%)

Так что, очевидно, все это сводится к выравниванию файлов. Но почему выравнивания файлов отличаются при сборке из командной строки? В расширенных настройках Visual Studio я вижу, что выравнивание файлов действительно установлено на 512:

alt text

Это свойство проявляется в файле проекта в PropertyGroup:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    ...
    <FileAlignment>512</FileAlignment>
</PropertyGroup>

Но обратите внимание на комбинацию $Configuration и $Platform? По догадке я попробовал это из командной строки:

msbuild /p:Configuration=Release /p:Platform="Any CPU" /t:Rebuild MySolution.sln

А потом вывод соответствует (по размеру) отлично!

Это единственная группа свойств для конфигурации выпуска, поэтому она, очевидно, используется MSBuild независимо от того, указана ли платформа. Чтобы доказать это, я изменил OutputPath в этой группе свойств, а затем собрал MSBuild в командной строке. Конечно же, он поднял новый каталог вывода.

Я попытался изменить выравнивание от 512 до 1024, а затем встроил его в командную строку. Он использовал это!

Почему необходимо явно указывать платформу, чтобы MSBuild мог подобрать выравнивание файла в 512 байт?

Ответы [ 2 ]

4 голосов
/ 01 сентября 2010

Почему необходимо явно указывать платформу

Потому что по умолчанию, вероятно, Debug|AnyCPU. Проверьте первый <PropertyGroup> в файле проекта, он должен содержать что-то близкое к:

<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>

, который устанавливает сборку по умолчанию, если Configuration или Platform не задано в командной строке. Эта первая группа также может устанавливать выравнивание файлов по умолчанию.

2 голосов
/ 02 сентября 2010

Просматривая историю файла моего проекта, я заметил, что свойства FileAlignment не было, пока я не установил его явно в Visual Studio (что я и сделал, придумывая свой вопрос).Файл проекта был обновлен с VS2008 до VS2010 (и я думаю, что VS2005 до VS2008 до этого), поэтому я предполагаю, что что-то сломалось на этом пути.

Итак, по крайней мере, сейчас я помещаю этовплоть до комбинации сломанных обновлений, и я запутался, когда писал вопрос.Я до сих пор не могу объяснить поведение, которое я видел (согласно моему сообщению), но, похоже, все выровнялось с тех пор, как FileAlignment был явно добавлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...