使用MSBuild指定解决方案的项目文件

143

我希望得到使用msbuild构建特定解决方案中项目的命令行,就像我们在devenv.com中所做的一样。在devenv.com中,我们可以使用以下命令行指定解决方案中的项目:

devenv.com /Build Release|x86 test.sln /project "testproject"

使用上述命令行,我可以使用devenv.com在test.sln中构建testproject。相同解决方案的msbuild命令行是什么。

谢谢


你为什么不直接将测试项目传递给msbuild呢? - Mark Smith
4
由于我无法再编辑我的评论,我的意思是直接引用项目而不是解决方案。"msbuild testproject /p:Configuration=Release /p:Platform=x86" - Mark Smith
我需要在不同的时间构建不同的项目。使用devenv.com很容易,只需指定该解决方案的项目即可。 - mystack
如果这是您唯一的问题,那么您应该能够使用msbuild在正确的时间构建所需的项目。您已经在解决方案上在不同的时间执行不同的命令,那么为什么不只是在正确的时间使用不同的msbuild命令引用项目呢?如果您的项目设置正确,它们应该能够找到所有引用,而不必使用sln文件。 - Mark Smith
2
可能是从命令行中构建解决方案中的一个项目的重复问题。 - StayOnTarget
5个回答

246
msbuild test.sln /t:project /p:Configuration="Release" /p:Platform="x86" /p:BuildProjectReferences=false

请注意,被分配给/t的是解决方案中的项目名称,它可能与项目文件名不同。
此外,正如在如何使用MSBuild.exe构建解决方案中的特定目标中所述:

如果项目名称包含字符%$@;.()',则用_替换指定目标名称中的这些字符。

您还可以同时构建多个项目:
msbuild test.sln /t:project;project2 /p:Configuration="Release" /p:Platform="x86" /p:BuildProjectReferences=false

如果要重新构建或清理项目,请将/t:project更改为/t:project:clean/t:project:rebuild


119
重要提示:如果你的项目名称中有“.”,在使用/t指定时需要将它替换为“_”。 - Watusimoto
5
为了构建多个项目,我的 MSBuild 使用 /t 参数重复指定每个要构建的项目:msbuild test.sln /t:project /t:project2 - Philippe
53
如果您正在使用解决方案文件夹,则需要在项目名称之前加上文件夹名称和斜杠。就像@Watusimoto上面提到的那样,如果名称中包含句点(.),则必须将它们替换为下划线(_)。最终会得到类似这样的东西:/t:SlnFolder\My_Project_name - Travis Parks
34
值得一提的是,“解决方案文件夹”并不是指文件系统中的文件夹,而是指“解决方案资源管理器”视图中的文件夹。 - joshbodily
5
在文件夹名称中我还得用下划线代替括号(GYP生成的项目),我猜所有特殊字符都会被替换成下划线。 - Maxime
显示剩余9条评论

23

实际上,MSBuild通过使用项目来工作而不是解决方案。解决方案仅用于将其解析为MSBuild内部的临时项目文件。您应该能够通过执行以下命令直接通过MSBuild构建感兴趣的项目。

"msbuild testproject /p:Configuration=Release /p:Platform=x86"

如果您直接使用项目而非解决方案,可能会遇到一个主要问题:如果您使用解决方案来表达项目之间的依赖关系,而不是添加对项目的引用,让构建系统自动处理依赖关系。

如果您正在使用 sln 文件强制执行构建顺序,则建议将这些依赖项直接集成到 proj 文件中,并从 sln 文件中删除它们。这样,您可以直接从 MSBuild 调用任何 proj 文件,并且项目将独立构建,无需任何其他工作。您真的应该将 sln 文件视为一组项目,以使在 Visual Studio 中的工作更轻松,而不是作为构建输入。


4
请指出如何从项目文件中强制执行构建顺序。谢谢。 - ProgramCpp
5
直接使用项目名称存在另一个问题。例如,您的解决方案中有5个项目。一些项目具有DebugPro配置,而其他项目则没有。如果使用所有项目都拥有的配置构建项目,则一切正常,但只有解决方案文件知道在选择DebugPro解决方案配置时要为每个项目使用哪个配置。 - Alex
@ProgramCpp 当您将一个项目的引用添加到另一个项目中时,它会自动确定需要先构建被引用的项目。 - jpaugh
这种方法的另一个缺点是项目中的相对路径是相对于解决方案文件解析的。一旦直接构建项目,相对路径就会改变。输出可能在其他地方,单元测试可能会查找错误的目录。 - Tomas Kubes
如果在项目配置中使用解决方案变量,例如$(SolutionDir),也可能会出现问题。 - Alex Che

9

将以下内容添加到构建脚本中,并运行一次。这将生成实际上 msbuild 将使用的确切目标和其他信息。

例如:如果项目名称或文件夹中有 .,则 msbuild 将期望在 . 的位置放置 _

发布为信息以供未来查找者使用。

set MSBuildEmitSolution=1

在获取信息后,使用所需的详细信息更新构建脚本。


6
如果你的项目名称或文件夹中有“.”,那么MSBuild将期望在“.”的位置使用“_”。 - hdev

7
为了做到这一点,你需要知道项目的目标名称(而不仅仅是项目名称)。
一种找到它的方法是使用 MSBuild 对你的 SLN 进行操作,并在设置一个名为“MSBuildEmitSolution”的特殊环境变量为值“1”后使用预定参数。
set MSBuildEmitSolution=1
msbuild my_stuff.sln /t:rebuild /p:Configuration=Release /p:Platform=x64

最近我不得不这样做,因为在嵌套目录中有一个非常特定的目标名称。所以从我的生成文件my_stuff.sln.metaproj中,我找到了这一行:

<Target Name="Utils\Firewall\FirewallUtils:Rebuild">

这意味着要使用的命令行是:

msbuild my_stuff.sln /t:Utils\Firewall\FirewallUtils:Rebuild /p:Configuration=Release /p:Platform=x64

2
这正是我所需要的。如果你不想运行它,这里有一个提示:你的目标是从当前路径到项目文件的文件夹结构,减去项目文件扩展名(在我的情况下是.csproj)。我<3 SO! - No Refunds No Returns

1

补充一点信息,执行项目文件夹中的msbuild命令将默认构建该项目文件,因为它是唯一存在的。

>msbuild

有多种使用msbuild的方式。您可以直接指定proj文件。

>msbuild helloworld.csproj -t:Build.

请查看msbuild文档以了解用法、项目文件要求以及构建项目而不是解决方案的好处。

MS MSBuild文档

正如mark-smith所提到的,以这种方式构建有好处。


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