How to build project in multiple configurations to automate the build process? - visual-studio

I have a solution, which contains a native project. For the main project to properly work, the following steps should be taken:
The native project has to be built in Release/x86 configuration
The native project has to be built in Release/x64 configuration
All .NET projects have to be built
Both binaries from steps 1 and 2 have to be placed in the main project's output folder.
Is there a way to configure project, so that all of those steps happen upon simply choosing "Build | Rebuild all"? I know of the batch build option, but I'd still have to execute step 4 manually.

I think you have to use msbuild script to build your project rather than VS IDE. Scripts are more flexible and can realize your requirements.
1) create a new file called build.proj and then add these on that file:
<Project>
<ItemGroup>
<!--include all c# csproj files to build these projects all at once-->
<NetProjectFile Include="**\*.csproj" />
<!--include the c++ proj files-->
<NativeProjectFile Include="**\*.vcxproj" />
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="#(NetProjectFile)" Targets="Restore;Build" Properties="Configuration=Debug;Platform=AnyCPU"/>
<!--OutDir is the path of the execute file ,pdb.... if you also want the intermediate files to be in the same folder, you should also use IntDir -->
<MSBuild Projects="#(NativeProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=x86;OutDir=xxx\xxx\"/>
<MSBuild Projects="#(NativeProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=x64;OutDir=xxx\xxx\"/>
</Target>
</Project>
3) Just run msbuild build.proj -t:Build to get what you want.

Related

How to add a project or target to msbuild solution that builds other projects in the same solution?

Wondering if there is an easy way to do what I want with Visual Studio solution.
I have a solution that has 10+ VC++ projects. These projects don't have any dependencies on each other. I want to create msbuild target on the solution that goes and builds all the sub projects.
Something like:
msbuild mysolution.sln /t:RebuildAll /p:Configuration=Debug
How do I add "RebuildAll" target to my solution that iterates all projects in the solution and invokes "Rebuild" target on them?
Thanks
According to your description I make some test, you can refer to the following steps:
Create a file named test.proj
Use this code in the file, remember to change your own solution path in the code:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectFile Include="Your solution path/**/*.vcxproj">
<Properties>Configuration=Release</Properties>
</ProjectFile>
</ItemGroup>
<Target Name="BuildAll">
<MSBuild Projects="#(ProjectFile)" BuildInParallel="true" />
</Target>
</Project>
Then use this msbuild command line to build your projects msbuild test.proj -t:BuildAll -v:normal -m:30.

Compile a list of projects with msbuild.exe

I have a VS solution which contains n-C++ projects. Is there any way to let msbuild.exe compile a specific subset of projects via command line?
msbuild.exe foo.sln /thisFlagWouldBeCool:project1;project2
I tried the /t flag for targets, but that doesn't seem to do it, since targets are not projects?
1.See How to: Build specific targets in solutions by using MSBuild.exe. As it states, you can use command like:
msbuild SlnFolders.sln -target:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean
More specific, if you have Project A, B, C in same solution(Test.sln), to build only A and B, you can use command like:
msbuild Test.sln /t:A;B /p:Configuration="xx" /p:Platform="xx"
Note: To build in this way, we should make sure the A.xxproj and B.xxproj are defined in xx.sln file. At least for VS, if we create a new Project C, the xx.sln won't be updated until we click the save all button.
2.And here's another direction which is suitable for some specific scenario:
We can right-click the Solution node in VS, choose add project=>empty project to add an empty project into the solution, let's name it MyBuildTool project.Unload it to edit its MyBuildTool.vcxproj file, add this kind of script into the bottom of it(within the Project tab):
<!--If you're trying to build subset of the solution, any build the projects with different settings-->
<Target Name="CustomBuild" AfterTargets="build">
<MSBuild Projects="..\**\B2.vcxproj" Properties="Configuration=Debug;Platform=x64;OutDir=xxx"/>
<MSBuild Projects="..\**\A2.vcxproj" Properties="Configuration=Release"/>
...
</Target>
<!--If you're building several projects in same settings-->
<Target Name="CustomBuild" AfterTargets="build">
<ItemGroup>
<ProjectsToBuild Include="..\**\A1.vcxproj"/>
<ProjectsToBuild Include="..\**\B1.vcxproj"/>
</ItemGroup>
<MSBuild Projects="#(ProjectsToBuild)" Properties="Configuration=Debug" BuildInParallel="true"/>
</Target>
</Project>
Then the MyBuildTool.vcxproj is now our build script, if in some specific situation we need to build several project, we can just run command msbuild.exe MyBuildTool.vcxproj. It depends on the usage of MSBuild Task.

csproj file settings for several build projects

I have this solution structute:
Solution.sln
|--WebUI.csproj (has Core.csproj as dependency)
|--Core.csproj
|--Tests
|--UnitTests
|--WebUI.UnitTest.csproj (has Core.csproj and WebUI.csproj as dependencies)
|--Core.UnitTest.csproj (has Core.csproj as dependency)
What should I add to WebUI.csproj to build WebUI.UnitTest.csproj and Core.UnitTest.csproj all together? (in my WebUI\bin folder I need these libs: WebUI.UnitTest.dll and Core.UnitTest.dll).
Thanks!
The direct method is that add WebUI.UnitTest project and Core.UnitTest project as dependencies for WebUI project. But the WebUI.UnitTest project already has WebUI.csproj as dependencies, this method does not work in your solution structure. If you just want to have WebUI.UnitTest.dll and Core.UnitTest.dll in your WebUI\bin folder, you can add a task in your WebUI.csproj to copy those files to the folder:
<Target Name="AfterBuild">
<PropertyGroup>
<SolutionDir>$([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))</SolutionDir>
</PropertyGroup>
<Exec Command=""$(MSBuildBinPath)\MSBuild.exe" "$(SolutionDir)\WebUI.UnitTest\WebUI.UnitTest.csproj"" />
<Exec Command=""$(MSBuildBinPath)\MSBuild.exe" "$(SolutionDir)\Core.UnitTest\Core.UnitTest.csproj"" />
<PropertyGroup>
<CopyFileOutput>$(SolutionDir)\WebUI.UnitTest\bin\Debug\WebUI.UnitTest.dll;$(SolutionDir)\Core.UnitTest\bin\Debug\Core.UnitTest.dll</CopyFileOutput>
</PropertyGroup>
<Copy
SourceFiles="$(CopyFileOutput)"
DestinationFolder="$(SolutionDir)\WebUI\bin"
/>
Note that: The stijn`s comment is right, you build the solution, WebUI.UnitTest.csproj and Core.UnitTest.csproj should get built already.
I have also added build steps of WebUI.UnitTest.csproj and Core.UnitTest.csproj in the WebUI.csproj so that you just only need to build the WebUI.csproj.

VS 2010 Solution Configuration build for a project context

I have a Visual Studio solution containing 30+ projects. There are 2 build configurations, Debug and Release. Ten of the project files (.csproj) are generated reasonably frequently using an external tool and the templates for that generation include the Debug and Release configurations. Modifying the templates to include additional configurations is not really an option.
So the problem I have is that I have a new project that is hosted in AppFabric/IIS. I'm using Web.Config transformations to update the Web.Config for deployment to 4 different environments: Development, Test, Staging, Production. I've add those contexts to the specific project using the Configuration Manager. That works so I can update the Configuration Manager for e.g. the Release build to use the Production context for the project. Right-clicking and building a deployment package for the project results in the appropriate transformation being applied to the Web.Config.
Now I want to automate the process so I have an MSBuild script:
<ItemGroup>
<BuildMode Include="Dev"/>
<BuildMode Include="Test"/>
<BuildMode Include="Staging"/>
<BuildMode Include="Prod"/>
</ItemGroup>
<Target Name="Build" DependsOnTargets="Package"></Target>
<!--
Build deployment package for each target environment
-->
<Target Name="Package" Outputs="%(BuildMode.Identity)">
<Message Text="Building %(BuildMode.Identity)"/>
<MSBuild Projects="..\SynchWorkflow\SynchWorkflow.csproj"
Targets="Package"
Properties="Platform=AnyCPU;Configuration=%(BuildMode.Identity);"/>
</Target>
Unfortunately this errors because it is trying to build e.g. a Prod configuration when it doesn't exist - Prod is only a context for the SynchWorkflow project. What I want to do is have the Prod context package generated using the Release configuration. Is that possible using the MSBuild task? Is there an extra setting I can provide to the MSBuild task in the Properties attribute that would allow this?
I added new solution configurations for each environment (without adding new project configurations) and then used Configuration Manager to set the contexts to Release for the dependent projects. Unfortunately this didn't work because the MSBuild task was building against the project file and not the solution. Resolved using Julien Hoarau's SO answer. Adding the new solution configurations was the correct approach but the linked answer closed the loop for me. The build script has been updated to the following:
<ItemGroup>
<BuildMode Include="Development"/>
<BuildMode Include="Test"/>
<BuildMode Include="Staging"/>
<BuildMode Include="Production"/>
</ItemGroup>
<PropertyGroup>
<PackageLocation>$(MSBuildProjectDirectory)</PackageLocation>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="Package"></Target>
<!--
Build deployment package for each target environment
-->
<Target Name="Package" Outputs="%(BuildMode.Identity)">
<Message Text="Building %(BuildMode.Identity)"/>
<MSBuild Projects="..\SynchWorkflow.sln"
Properties="Platform=Any CPU;
Configuration=%(BuildMode.Identity);
DeployOnBuild=true;
DeployTarget=Package;
PackageLocation=$(PackageLocation)\SynchWorkflow.%(BuildMode.Identity)Package.zip;"/>
</Target>
The script builds against the solution file and generates the correct package for each target environment. For the purposes of the example script I'm creating the packages in the MSBuildProjectDirectory which is a bit suboptimal.

run MsBuild tasks (targets?) after the solution is built?

Since this question seems to have baffled / underwhelmed SO I will rephrase it with a partially formed idea of my own.
Could I somehow set up a batch file or something that runs after the whole solution is built, and this batch file would call msbuild to build specific targets inside a certain project? In order for it to work, I would have to somehow force msbuild build the target without regard to whether it thinks it's "up to date", because that is the core issue I'm butting up against.
Since you are dealing with building specifically you may want to replace your batch file with an MSBuild file. For example:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<SolutionsToBuild Include="MySolution.sln"/>
<Projects Include="Proj1.csproj"/>
<Projects Include="Proj2.csproj"/>
<Projects Include="Proj3.csproj"/>
</ItemGroup>
<Target Name="BuildAll">
<!-- Just executes the DefaultTargets (Build) -->
<MSBuild Projects="#(SolutionsToBuild)"/>
<!-- Call Rebuild if you think its not building correctly -->
<MSBuild Projects="#(Projects)"
Targets="Rebuild"/>
</Target>
</Project>
Then you just invoke msbuild.exe on this file with:
msbuild.exe Build.proj /t:BuildAll
Since you said that you want to build specific projects after the solution is built just put those into the Projects ItemGroup as shown and use the MSBuild task to build them after the solution has been built. I've specified the Rebuild target to make sure you get a clean build.

Resources