In the solution I have some dependent project configured as SDK style projects:
Proj A responsible for doing some routine as MsBuild task
Proj B project which requires such processing for compiling correctly
Task is configured at Proj B as MsBuild target with attribute BeforeTargets="CoreCompile".
Based on that Proj A should be fully compiled before running task on Proj B compilation.
Both projects has different compilation target (NetStandard20 and Net462). Therefore I couldn't make a direct reference but do solution-wide project dependency with setting property AddSyntheticProjectReferencesForSolutionDependencies as false (otherwise msbuild tries to make project dependency forcible).
In that setup, MsBuild sometimes fails on compilation: Proj A started to compile but haven't finished in time when Proj B run the task.
MSBuild is started on CI machine with key /m.
Any ideas are welcomed.
In this case you actually do want a synthetic project reference but there is a subtle issue in MSBuild at the moment that creates some issues across project references if the project having the dependency is multi-targeting. This is fixed in 15.9.
Please try it out in the visual studio preview version of 15.9 (at the time of writing: 15.9 Preview 2).
If you don't want to wait, you can add a similar project reference in the csproj file yourself:
<ItemGroup>
<ProjectReference Include="..\other\project.csproj"
ReferenceOutputAssembly="false"
LinkLibraryDependencies="false"
CopyLocal="false"
SkipGetTargetFrameworkProperties="true"
GlobalPropertiesToRemove="TargetFramework"
/>
</ItemGroup>
Related
I want to run a SonarQube analysis on msbuild proj files.
The build consists of one .proj file. This file builds several other .proj files.
When I run the build, SonarQube prints this error message:
The SonarQube MSBuild integration failed: SonarQube was unable to collect the required information about your projects.
Possible causes:
1. The project has not been built - the project must be built in between the begin and end steps
2. An unsupported version of MSBuild has been used to build the project. Currently MSBuild 14.0 and 15.0 are supported
3. The begin, build and end steps have not all been launched from the same folder
4. None of the analyzed projects have a valid ProjectGuid and you have not used a solution (.sln)
I checked and the last point is probably the problem.There is no .sln but each of the called .proj files has a Guid added, but not the top one. (it worked fine with .njsproj files previously, which had a guid)
Project Guid is provided like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{B1E36758-8A06-4793-A7D2-216DE578732D}</ProjectGuid>
</PropertyGroup>
....
</Project>
I also tried without curly braces.
I'm not really sure what sonarqube is expecting.
Is SonarQube working with .proj files?
I'm facing a weird issue while trying to build using MSBuild.
I'm using MSBuild to build a solution file with /m (parallel build) and BuildProjectReferences set to true.
Suppose I have A.vcxproj and B.vcxproj in the sln file with B having a project reference to A.
What happens is A project starts to build first and while its in the middle of compiling, B project starts to build in another process (since parallel builds) and it would invoke building A.
Now this causes a race condition because we have two processes trying to build the same project A and I would see access issues.
Ideally MSBuild should not invoke building B if A hasnt finished building or if it does invoke B then detect that A is still building and wait for it to finish.
None of this happens. Also, this happens only with MSBuild - doesnt happen if I try to build the solution file from VS2015 IDE.
Any idea why MSBuild behaves this way?
Finally found the solution to my problem
MSBuild expects that the project dependencies be added in two ways
1. In the vcxproj itself, add all the dependent projectreference
2. In the sln file too, define the projectdependencies.
The following VS blog actually states the opposite- For example - https://blogs.msdn.microsoft.com/vcblog/2010/02/16/project-settings-changes-with-vs2010/ states that projectdependencies and projectreference are analogous and use only one specifically projectreferences.
This may be true when you build using VS IDE but not for MSBuild. It needs the project dependencies to be defined on both ProjectReference and ProjectDependencies.
Hope this helps anyone who hit into the same issue as mine.
Our continuous delivery set-up, until recently, was delivering Service Fabric packages using the following command:
msbuild SFApp.sfproj /t:Package
This was necessary because the target Package is unavailable at the solution level. I.e. The command
msbuild SFSolution.sln /t:Package
Fails, as the target does not exist.
As our dependency mesh grows, it gets to a point in which most interfaces projects will not build without a solution file (to work around the "OutputPath does not exist" red herring). There seems to be a way to do that according to this answer. Unfortunately, while targets like Clean work…
msbuild SFSolution.sln /t:SFApplication:Clean
(…snip…)
Build succeeded.
0 Warning(s)
0 Error(s)
…the target Package won't!
msbuild SFSolution.sln /t:SFApplication:Package
(…snip…)
Build FAILED.
"SFSolution.sln" (SFApplication:Package target) (1) -> SFSolution.sln.metaproj :
error MSB4057: The target "SFApplication:Package" does not exist in the
project. [SFSolution.sln]
0 Warning(s)
1 Error(s)
(Solution/project folders/names omitted/paraphrased for clarity. I can provide the actual logs if necessary.)
So the question is: how could I, using the Command Line, build one project using the Package target and the solution file?
Or how can I otherwise package a Service Fabric application from the command line?
It's bad idea to compile sfproj file(and any other project file) without sln, because it can bring wrong content to its output from referenced projects. Only solution has a knowledge about what project to compile in what configuration.
To make Package similar to "Right Click->Package" in VS:
Just add to your sfproj the following target
<Target Name="ForcePackageTarget" AfterTargets="Build" Condition="'$(ForcePackageTarget)' =='true'">
<CallTarget Targets="Package"/>
</Target>
And then running normal build on solution you may trigger the package step by /p:ForcePackageTarget=true :
msbuild yoursolution.sln /t:Build /p:ForcePackageTarget=true /p:Configuration=Release /p:Platform=x64
Actually it performs two-in-one steps, build and package, with respect to Solution Configurations on all referenced projects
MSBuild only supports a small set of target names that can be specified at the solution level. As you've discovered, Package is not one of them. You'll need to execute two separate calls to MSBuild: one which builds the solution and one which calls the Package target on the sfproj. The Package target of an sfproj has a dependency on the Build target so it will ensure that the sfproj and its project dependencies are built.
I had the same problem and fixed it by changing the Platform in the failing projects to explicitly build for x64.
Click Build > Configuration Manager and make sure that the assemblies are compiled for the x64 platform, that should also set the Output Paths in the corresponding .csproj files.
The actual command line action that is being executed is this:
"C:\Program Files (x86)\MSBuild\14.0\bin\amd64\msbuild.exe" "C:\agent\_work\1\s\Project\SFProject.sfproj" /t:Package /p:platform="x64" /p:configuration="release" /p:VisualStudioVersion="14.0"
Use the below script.
C:\Program Files (x86)\Microsoft Visual Studio 14.0> msbuild "Fabric.sfproj" /t:Package /p:Configuration=Release
Service fabric requires Target to be set in x64 platform,
So change all you reference projects target to x64 platform.
you can do this by using configuration properties of your solution. If x64 is not listed in 'Configuration Properties' click configuration manager in the same window and under platform column for the required project add new project platform as x64.
Hope this works for you.
We have had the exact same problem as you had and I have been looking around for a solution all over the web and did some experiments. Those are the steps that worked for us:
Don't manually add a target anywhere as suggested by other answers on StackOverflow. Not necessary. Especially in a CI environment, you want to build the projects separately anyways.
Prepare the projects in the Solution: Change the target platform for all projects to x64
Build the application
msbuild.exe SFAplication.xproj /p:Configuration=Release /target:rebuild
Package the App
msbuild.exe SFAplication.sfproj /p:Configuration=Release /target:Package
Following Situation:
2 Team Projects
Dvelop of Team Project A added Project References of Team Project B to their projects.
For speeding up the Build I want to replace the project references with referencing the dll's directly.
My Idea:
in the csproj of Team Project A:
<ProjectReference Condition="'$(IsDesktopBuild)' == 'true'" Include="[Project Reference] >...
in the TFSBuild.proj
<AdditionalReferencePath Include="[buildoutputOfTeamProjectB]" />
OR
Disable SolutionToBuild and use the csproj files directly.
Thanks for your suggestions.
I would suggest that each project have a dependencies folder that contains the appropriate dlls that are required for each project. When a project that is depended upon is built it would be up to you to automatically update the dll in the dependencies folder or not via your build process (cruise control/nant/msbuild?). However, I would also give some consideration around deploying versions of the depended upon dll just in case you blow up the dependent projects usage of that dll. It would suck for someone to update their project (the depended on project), kick off a build, deploy their build output to the dependent project) only to break the project that relies on their code base. That sounds like a fragile way of managing dependencies.
I have a solution with several projects in it. Let's say
project A depends on projects B and C
project B depends on project C
When I run my solution on the local machine VS builds each project once and it takes 1 minute. However, on our build machine it takes about 4 minutes to build and, as I can understand from the MSBuild logs it goes like this:
build A -> build B for A, build C for A
build B -> build C for B
So it builds some projects several times... How can I speed up the build process?
P.S. It's not a question of 3 extra minutes, I just wonder why is it so different from my local machine build?
I am not sure about your build order. Sometimes TeamBuild can look like it is building projects over and over but it is building for different configurations. Take a look and make sure you have not defined multiple FlavorsToBuild.
Also, if you don't want to do a fresh check out and rebuild every time, you can define this at the bottom of your TFSBuild file.
<PropertyGroup>
<IncrementalBuild>true</IncrementalBuild>
</PropertyGroup>-->
Put that right before the </Project> tag.
This sample seems to work for me. TestLib.Extra depends on TestLib. If I change something in TestLib, both projects will build. If I change only in TestLib.Extra, only that one will build, and if I don't change anything at all, they will just report Skipping target "CoreCompile" because all output files are up-to-date and so on.
<Target Name="Build">
<MSBuild Targets="Build" Projects="TestLib\TestLib.csproj" />
<MSBuild Targets="Build" Projects="TestLib.Extra\TestLib.Extra.csproj" />
</Target>
The trick is to use the "Build" target of the projects, rather than "Rebuild". The difference between these is essentially the same as the difference between the "Build" and "Rebuild" commands in the build menu in Visual Studio.
Edit
This works well also if the projects are included in a solution file, and you specify the solution to build instead:
<Target Name="Build">
<MSBuild Targets="Build" Projects="TestLib.sln" />
</Target>
Maybe like our's, your build server is a virtual machine (10x at least slower).
Also TFS (and maybe others), does a fresh checkout on build, so it will have to build all the projects regardless.
Are you using the /maxcpucount switch? There may be a difference in number of processors between your local machine and the build machine. This setting can also be different between your msbuild file and the visual studio setting which could also explain the difference you're seeing in build times.
I do this as follows. It is somewhat complicated custom build system but the basic idea is.
The dlls which are reused in many solutions are build to a known folder. This is achieved my using a msbuild project file that builds these common dlls.
When building other csproj files in a solution we copy the csproj files then use xslt manipulation to replace the project references with dll refernces for those common dlls.
The build scripts then build these changed csproj files using custom msbuild project files we maintain corresponding to each solutions. We don't build .sln files. These custom project files is a itemgroup of .csproj files in correct dependency order.
Maybe this can help you in achieving what you want.