为什么 MSBuild 需要明确设置目标平台?

3
对于我的一个简单项目,在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,即6144字节。头部大小的差异为0xE00,即3584字节。这两个差异之和为9728字节,这解释了差异。文件对齐方式的差异为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个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4

为什么需要明确指定平台?

因为默认可能是 Debug|AnyCPU。检查项目文件中的第一个 <PropertyGroup>,它应该包含类似于以下内容:

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

如果在命令行上没有设置ConfigurationPlatform,则会设置默认构建。这个第一组也可能设置默认文件对齐方式。


@Richard:我重新阅读了我的问题,我认为它已经足够清晰了。你甚至引用了我说的“指定平台”,而不是“指定配置和平台”,所以我不确定混淆来自哪里。 - Kent Boogaart
1
@Kent:我只是在免费帮助你。请将你的MSBuild文件缩减到最短,以显示问题(删除所有可以删除的内容),并提供能够显示和不能显示问题的命令行:然后我可以再次查看它。 - Richard
@Richard:希望你没有生气,因为我并没有恶意。我无法简单地重现这个问题,这就是为什么我在我的问题中发布了我所知道的一切。我已经发布了自己的“答案”,解释了发生了什么事情。感谢你的帮助(+1)。 - Kent Boogaart
@Richard:我也是这么想的,但是当我尝试时无法重现。话虽如此,当我在2010中创建一个新项目时,它会将FileAlignment属性添加到通用属性组中,而我的错误项目文件将其放在Release|Any CPU组中。我认为可能发生的情况是升级时完全省略了它,而VS默认为256,而MSBuild默认为8192。然后当我在VS中编辑设置时,它决定将其添加到Release|Any CPU组中,因为它不在通用组中。如果我有机会,明天可能会测试这个理论。 - Kent Boogaart
@Kent:这可以解释一些问题。有时我会发现手动编辑项目文件(卸载项目以获取直接打开x.zzproj文件的选项)可能更容易,特别是在多个配置中进行100%一致的更改。或者进行IDE不直接允许的更改(在解决方案文件夹中引用多个项目的x.sn文件)。 - Richard
显示剩余5条评论

2
浏览我的项目文件历史记录时,我注意到在显式设置它之前,没有FileAlignment属性。该项目文件已从VS2008升级到VS2010(我认为之前是从VS2005升级到VS2008),因此我假设在升级过程中出现了一些问题。 所以,至少现在,我将这归因于损坏的升级和我在撰写问题时混淆自己的事情。我仍然无法完全解释我看到的行为(如我的帖子),但自从明确添加了FileAlignment以来,事情似乎已经得到了纠正。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,