对于我的一个简单项目,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
init数据大小的差异是0x1800或6,144字节。标头大小的差异是0xE00或3,584字节。这两个差异的总和是9,728字节,这是造成差异的原因。文件对齐的差异是3,584字节。
再往下看,我看到了:
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:
此属性显示在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字节的文件对齐?
答案 0 :(得分:4)
为什么有必要明确指定平台
因为默认值可能是Debug|AnyCPU
。检查项目文件中的第一个<PropertyGroup>
,它应包含以下内容:
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
如果未在命令行上设置Configuration
或Platform
,则设置默认构建。第一组也可能是设置默认文件对齐。
答案 1 :(得分:2)
浏览我的项目文件的历史记录,我注意到在Visual Studio中明确设置它之前没有FileAlignment
属性(我在编写问题时就这样做了)。项目文件已从VS2008升级到VS2010(之前我认为VS2005到VS2008)所以我假设在此过程中出现了一些问题。
所以,至少现在,我把它归结为破碎升级的组合,让我在写这个问题时感到困惑。我仍然无法完全解释我所看到的行为(根据我的帖子),但事情似乎已经自我调整,因为明确添加了FileAlignment
。