MSbuild solution with referenced DLL from a project within the solution - compilation

I am trying to get our continuous integration server (cruise control .net) working with our solution. From cruisecontrol i call msbuild to build the solution and i'm running in some problems, let me explain the structure of the solution:
4 Projects:
DataAccess
BusinessEntity
BusinessLayer
(Project A)
Project A is the actual project with all the user forms etc.
This project has references to the other 3 projects.
When compiling in Visual Studio, everything works of course..
From what i understand is that MSBuild works quite different from VS.
When building project A with msBuilds i get the following error:
C:\CI\Project A\Source\Project A\General.vb(859,33): error BC30007: Reference required to assembly 'System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' containing the base class 'System.EnterpriseServices.ServicedComponent'. Add one to your project. [C:\CI\Setra\Source\Project A\Project A.vbproj]]]></message>
The funny thing is that Project A has no reference at all to the mentioned assembly. But the referenced DLL's in project A do have.
When i compile the other projects (those that generate the DLL's) with msbuild, the build succeeds.
I have the feeling it has something to do with the way the DLL's are referenced in the main project, but i can't seem to figure it out..
Any help or suggestions is greatly appreciated !!

This blogpost, despite being quite old, should answer your question. Some more useful info on how to approach this problem can be also found here.
In general, MSBuild has problems resolving secondary, ternary etc. references directly. More up to date article can be found here. I haven't tested this approach, though it seems quite good and easy to implement at the first sight:
Paste the following code into the file before the last tag:
<Target Name="AfterResolveReferences">
<!-- Redefine referencepath to add dependencies-->
<ItemGroup>
<ReferencePath Include="#(ReferenceDependencyPaths)"></ReferencePath>
</ItemGroup>
</Target>

This may be the issue
Project A is the actual project with all the user forms etc.
it has references to 3 DLL's which are created by the other projects.
In Solution Explorer, right click References and add a new Reference.
Do not browse for the dependency under Assemblies, instead go to Projects, Solution, choose the DataAccess, BusinessLayer, and BusinessEntity projects.
Now remove the File references & save the project file. When you rebuild, msbuild will detect these ProjectReference dependencies

Related

VS2010/MSBuild 4.0 building external projects

It seems that since VS2010 and MSBuild 4.0, VisualStudio and MSBuild are able to resolve and build project references that are not located within the solution.
Let us create an example to be more concrete. Create a solution called Solution1 with a C# project named A and another project called B. In project B, add a reference to project A. Now create a new solution called Solution2 and click "Add Existing project" and select Project B. There is a warning that can be seen in Solution Explorer and the Warning List.
The trick is that even with "warning as error" we are able to build Solution2.sln. Actually, project A is found
and built by Visual Studio or MSBuild. Let us verify this by opening a VS2010/VS2012 command line and execute the following commands:
msbuild <dirPathToSolution1> Solution1.sln /t:clean **cleaning up solution1 with project A"
msbuild <dirPathToSolution1> Solution2.sln /t:build
ProjectA is effectively built and worse: the warning mentioned above is not even raised there. With previous versions of Visual Studio such situation could not happen (I have tested it with msbuild 3.5 and VS2008).
However, in our situation we would like to prevent such things. Indeed, we have a large source repository with several solutions and many committers. We are reorganizing our dependencies aiming finally to the extraction of smaller repositories. Meanwhile, we do not want developers to add hidden project dependencies without seeing it. We would like to allow only project references "inside" a solution, leaving other dependencies to assembly references.
So the question is "Is there a way, to prevent such solution such as Solution2 to build ?". Ideally, it should not compile with both VS2012 and MSBuild. However a solution involving only the MSBuild command line would do thanks to our Continous Integration.
edit I checked Microsoft.Common.Targets and there does not seem any way to achieve what you want. Either project references are built, or they are not (this is for instance influenced by the BuildProjectReferences flag of my original answer). There is no way to build them selectively depending on which solution they are in unless I'm missing something - which is mainly because project references are set on the project level, not on the solution level: in your project file there is an MsBuild ItemGroup named ProjectReferences and that is used. (Actually this makes some sense: if you ask MsBuild to build projectB.csproj, and B says it references A, then no solution comes into play and you could expect it to build A, after all you are referencing it).
Now as I understand it, you want to prohibit referencing across directories whose structure happens to be represented by solutions. If that is the case, and you really need this, you could probably get away with a tool that parses the MsBuild log and looks for lines like
Project "somedir\projectB.csproj" (2) is building "someOtherDir\projectA.csproj" (3) ...
then extract the directory info from it and make the tool raise an error when they do not match. Then incorporate the tool in your CI server and feed it with the msbuild log files.
original answer
Try with /p:BuildProjectReferences=false on the command line. As the name suggests it will disable building of referenced projects. When building solution1, this should not be a problem since projectA will be built anyway as it is in the solution. However when building solution2, it won't build projectA and you'll get a build error.

warning : All projects referencing MyProject.csproj must install nuget package Microsoft.Bcl.Build

I have an ASP.NET MVC 4 app developed in VS 2012. The app consists of a main project (MyProject), a unit-test project (MyProject.Tests), an Azure deployment project (MyProject.Azure), and a couple of general-purpose library projects.
When I right-click on either the solution or the main project and select Manage NuGet Packages, I see a bunch of Microsoft updates that have apparently become available in the last month or so. If I click on the Update All button then the updates are apparently installed without any obvious problems, but when I build the solution I get this error message TWICE:
warning : All projects referencing MyProject.csproj must install nuget package Microsoft.Bcl.Build
Ok, so I have two projects that reference MyProject: MyProject.Tests and MyProject.Azure. I can right-click MyProject.Tests, select ManageNuGet Packages, and add Microsoft.Bcl.Build. That gets rid of one of the two warnings. But VS does not give me an option to manage NuGet packages for the MyProject.Azure project.
How do I add the Microsoft.Bcl.Build package to the Azure deployment project?
EDIT:
Thanks to user swell, I now know that a Microsoft Connect issue for this problem has been opened here.
The answer provided by TheESJ is correct, however the wording wasn't clear to me. Since I cannot comment on the answer, I will provide more details here. Specifically, I was having this problem with an Azure project and the following workaround was required to make the warning go away:
When you double-click the warning in VisualStudio, you will be taken to the BclBuildValidateNugetPackageReferences target in the Microsoft.BclBuild.targets file. Above the actual target element, you should find a large comment block that talks about disabling the project reference checks. Since Azure projects cannot have any library references, it is impossible for those Azure projects to fulfill the requirements of this particular build target.
The solution? Disable reference checking from the Azure project since it is impossible to actually add a nuget package reference.
EXAMPLE
So, assume we have two projects: MyAzureProject.ccproj which references MyProject.csproj. Follow these steps:
Right-click on "MyAzureProject" in the Solution Explorer and select "Edit Project File."
Find the project reference to "MyProject." It should look something like:
<ProjectReference Include="..\MyProject\MyProject.csproj">
<Name>MyProject</Name>
<Project>{1d99490e-d140-4897-9890-238e673a5864}</Project>
...
</ProjectReference>
Add the following element inside of the ProjectReference element:
<Properties>SkipValidatePackageReferences=true</Properties>
Your project reference should now look like this:
<ProjectReference Include="..\MyProject\MyProject.csproj">
<Name>MyProject</Name>
<Project>{1d99490e-d140-4897-9890-238e673a5864}</Project>
...
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
Right-click on "MyAzureProject" in Solution Explorer and choose "Reload Project."
You should now be able to rebuild and the error should be gone.
If you double click the warning it gives you instructions for disabling the warning.
It is safe to disable for projectreferences from projects that don't yet support Nuget.
See below portion in bold copied from Microsoft.Bcl.Build.targets.
BclBuildValidateNugetPackageReferences
This target can be disabled for a project reference by setting SkipValidatePackageReferences=true for the reference:
<ProjectReference Include="..\pcl\pcl.csproj">
<Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
<Name>pcl</Name>
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
I faced the same issue and was trying to update Microsoft.Bcl.Build.targets; which did not help.
After some investigation found that .csproj file of the Azure Service project must be modified to include <Properties>SkipValidatePackageReferences=true</Properties>.
This was not apparent from the answer of #TheESJ and so decided to post separate answer. Thanks to #TheESJ.
I encountered this issue a number of times, and the Properties method does indeed work, but when dealing with a Wix project, I had to do the following instead:
<AdditionalProperties>SkipValidatePackageReferences=true</AdditionalProperties>
When I used the Properties Xml node, I got a new error:
The OutputPath property is not set for project
'MyInstallerProject.csproj'. Please check to make sure that you
have specified a valid combination of Configuration and Platform for
this project. Configuration='Debug' Platform='x86'. This error may
also appear if some other project is trying to follow a
project-to-project reference to this project, this project has been
unloaded or is not included in the solution, and the referencing
project does not build using the same or an equivalent Configuration
or Platform.
After failing to resolve the issues with any of the above answers, I simply followed the instructions contained within the Microsoft.Bcl.Build.targets file (displayed after double clicking on the error in the build output window).
I unloaded my project (referencing Azure packages), encountering the error. Edited the project file and inserted the following...
<PropertyGroup>
<SkipValidatePackageReferences>true</SkipValidatePackageReferences>
</PropertyGroup>
...at the top of the project file before the first PropertyGroup.

Make Visual Studio not to compile any projects

Is it possible to tell VS not to recompile some projects every time and use already compiled dll-s instead?
You can exclude any project from building in Configuration manager. Just unselect desired projects in Build column. You still will be able to debug those projects.
Instead of project references, you can add the compiled DLLs as references.
Any such referenced project will not rebuild if not changed.
However, since the references will now be to DLLs, you need some strategy to keep them synchronized and up to date with your code.
As I understood your question, you have a solution with multiple projects and you seem to have dependency of some of them on some other.
VS will always compile all the "loaded" projects. But when you add a reference to a project, add it directly to a (preferred) DLL assembly file, and not to one of the projects. This way the other project will be compiled but you are referencing the same DLL assembly over and over. Since if you reference the project, the output of the project is always what you reference actually.

VS2010 project dependencies

I have a c++ project in VS2010 and a c# project that is to consume this c++ project output (it uses it for p/invoke). I was thinking that I could ensure that the c++ project was build before the c# project by editing the "Project dependencies..." in the solution but this does not seem to have any effect, the build on my buildserver does not respect this setting (I'm using TeamCity to bootstrap an MSBuild file that builds the entire solution file)
I think this used to work, has anything changed with VS2010? Or should I declare the dependency in another way?
SOLUTION: The trick was to hand-edit the csproj file outside VS2010 and add a section like this:
<ProjectReference Include="..\CobraLib\CobraLib.vcxproj">
<Project>{598506DA-91DA-4F25-948D-A14CB16ABEBA}</Project>
<Name>CobraLib</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
That made the build server process my projects in the correct order. Only caveat is that VS2010 displays an error on the project reference ("not a .NET project") but otherwise things are working as I intended

What do you do about references when unloading a project in Visual Studio?

When you unload a project in Visual Studio, any referencing projects get warning triangles on their reference to the unloaded project. I've written myself a macro to do clever stuff (detect add/remove of project and transform any references from-to file/project dependency), but I can't believe that I'm not missing something much simpler. How can the unload function be any use if I have to go around manually changing references (and it breaks the 'personal solutions/shared projects' team development paradigm).
(This question is related to answers to this question about structuring large solutions in Visual Studio - some answers mentioned having solutions with lots of projects, but 'unloading' unused projects to improve performance.)
For my projects, I create an assemblies folder which the projects automatically copy into from a set location to which other projects copy builds.
Post-build for referenced assembly's project:
if not exist "C:\builds\Project1" md "C:\builds\Project1\"
copy "$(TargetDir)$(TargetName).*" "C:\builds\Project1\"
Pre-build for referencing projects:
if exist "c:\builds\Project1\" copy "c:\builds\Project1*.*" "$(ProjectDir)assemblies"
The project file points to its assemblies subfolder for references so even if the source projects are unloaded from the solution, the last-built assemblies will be used without the performance problems of having the whole project in memory while developing.
What are the advantages of having projects in the same solution if you use file references?
If your app.exe uses utils.dll and you change the code for utils.dll, then if it's in the same solution VS will notice the dependency and recompile both. If it's not in the solution you'll have to jump out, recompile utils.dll seperately, then jump back in and recompile app.exe.
This becomes either more or less important depending on how many other dll's your exe is referencing, and how often they change (in team environments shared dll's change often in my experience).
There is also the side effect that if you have 100 projects in VS it will take a long time to process them all just to figure out if they need recompiling or not.
Unloading projects is meant to be a temporary action so you can edit the actual project file as XML (text). If you want to completely remove a project from your solution, you should use the "Remove" menu option, which will take care of removing any references to that project.
One advantage to using project references is that it allows you to easily debug through the code. It also automatically ensures that you are using the correct configuration build (ie, if you are building in "Debug" mode it will use the Debug version of the assembly). That being said, you loose some determinisim about which version/build of the dependent project you will pick up - project references mean you always use the latest.
Yes, for Visual Studio to determine build dependencies it must be able to see and build all of the projects which would mean project references.
I've just had a eureka moment reading through MSDN doc on structuring solutions and projects.
What I hadn't noticed is that in a multi-project solution, the context menu in the Solution Explorer proposes a Project Dependencies popup. Here you can define the project dependencies manually, if you haven't defined them by project references between projects.
See here (MSDN link, so will self destruct after a few weeks)

Resources