Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild solution command line output to individual folders

Currently, I have the following MSBuild command:

msbuild 
    /t:Build 
    /p:Configuration=Release 
    /p:OutputPath=C:\MySolutionOutput\ 
    MySolution.sln

Which compiles, however, I have multiple projects in my solution. When I do a build this way with the solution file, it copies all project outputs to the same directory, and the output from Project2 overwrites the output from Project1 (or whatever order they're built in).

Instead, I want MSBuild to put each project into a subfolder of the project name.

msbuild 
    /t:Build 
    /p:Configuration=Release 
    /p:OutputPath=C:\MySolutionOutput\$(ProjectName)
    MySolution.sln

However, the $(ProjectName) syntax does not work as it literally makes a folder called $(ProjectName).

How do I make MSBuild solution building output each project to a subdirectory of the OutputPath, preferably without making MSBuild xml files, or building each project individually?

To illustrate further, my projects are as follows.

+ Project 1
    + File1.txt
    + File2.txt
    + ReadMe.txt

+ Project 2
    + File3.txt
    + File4.txt
    + ReadMe.txt     

What my build outputs

C:\MySolutionOutput\File1.txt
C:\MySolutionOutput\File2.txt
C:\MySolutionOutput\File3.txt
C:\MySolutionOutput\File4.txt
C:\MySolutionOutput\ReadMe.txt 
^-- (this is the 2nd readme, project 1's readme gets overwritten)

What I want

C:\MySolutionOutput\Project 1\File1.txt
C:\MySolutionOutput\Project 1\File2.txt
C:\MySolutionOutput\Project 1\ReadMe.txt

C:\MySolutionOutput\Project 2\File3.txt
C:\MySolutionOutput\Project 2\File4.txt
C:\MySolutionOutput\Project 2\ReadMe.txt
like image 540
Matthew Avatar asked Aug 07 '14 20:08

Matthew


1 Answers

When building a solution using msbuild, it internally transforms the solution into an msbuild xml file which builds all projects and passes properties like OutputPath to it, and afaik there isn't a way to interfere with how this behaves. One possible solution does require you to write msbuild files yourself, but the modifications are really minor. You don't mention which project type you're using but the principle is the same for any type, and here's a sample for C# projects:

  • create a common file which allows overriding OutputPath in the way you want it, but does nothing unless specifically told to in order to keep existing behaviour if needed
  • import that file in each project
  • specify custom output directory on the command line

msbuild file, say outputpath.props:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OutputPath Condition="'$(OutputPathBaseDir)' != ''">$(OutputPathBaseDir)\$(MSBuildProjectName)\</OutputPath>
  </PropertyGroup>
</Project>

import in each project; here I am using a relative path but you could reference eg $(SolutionDir) etc; for c# projects, insert this line right before the one shown

<Import Project="..\outputpath.props" />
<!--the below is an existing line in every c# project-->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

now build:

msbuild mysolution.sln /p:OutputPathBaseDir=C:\MySolutionOutput
like image 87
stijn Avatar answered Oct 12 '22 18:10

stijn