使用MSBuild构建解决方案时如何自定义输出与中间目录?
嘿,你的思路方向完全正确,但有个关键细节需要调整,才能完美实现你想要的目录结构,我来帮你梳理清楚:
先明确你的需求对比
默认目录结构
Solution.sln
├─Project1
│ ├─bin <- project 1 output
│ └─obj <- project 1 intermediate output
└─Project2
├─bin <- project 2 output
└─obj <- project 2 intermediate output
目标目录结构
Solution.sln
├─bin <- project 1 AND 2 output
└─obj
├─Project1 <- project 1 intermediate output
└─Project2 <- project 2 intermediate output
命令行方案的调整
你用msbuild指定参数的思路是对的,但 IntermediateOutputPath不能只设为../obj/——如果多个项目共用同一个中间目录,会出现文件冲突的问题。你需要给每个项目的中间路径加上项目名称,这样就能自动生成obj下的项目子文件夹了。
完整的命令行应该是:
msbuild Solution.sln "/p:OutputPath=../bin" "/p:IntermediateOutputPath=../obj/$(MSBuildProjectName)/"
OutputPath=../bin:所有项目的输出文件都会统一放到解决方案根目录的bin文件夹,这部分和你想的一致$(MSBuildProjectName)是MSBuild内置变量,会自动替换为当前项目的名称,这样每个项目的中间文件都会放到obj/Project1、obj/Project2这样的子目录里,完全匹配你的目标结构
更推荐的持久化配置方案
如果不想每次编译都输入长长的命令行参数,你可以在解决方案根目录创建一个名为Directory.Build.props的文件,内容如下:
<Project> <PropertyGroup> <!-- 统一输出目录到解决方案根目录的bin文件夹 --> <OutputPath>$(SolutionDir)bin\</OutputPath> <!-- 每个项目的中间文件放到obj下的对应项目子文件夹 --> <IntermediateOutputPath>$(SolutionDir)obj\$(MSBuildProjectName)\</IntermediateOutputPath> </PropertyGroup> </Project>
这个文件会被解决方案下的所有项目自动继承,不管你是用Visual Studio编译,还是用msbuild命令行,都会自动应用这个目录配置,非常省心。
额外优化提示
如果你的项目需要区分Debug/Release等不同配置,可以调整路径加入*$(Configuration)*变量,避免不同配置的文件混在一起:
<Project> <PropertyGroup> <OutputPath>$(SolutionDir)bin\$(Configuration)\</OutputPath> <IntermediateOutputPath>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\</IntermediateOutputPath> </PropertyGroup> </Project>
这样编译Debug版本时,输出会到bin/Debug,中间文件到obj/Project1/Debug,Release版本同理,结构更清晰。
内容的提问来源于stack exchange,提问作者dialer

