To prevent circular dependency, i had to make a reference from (lets say) project A, to B's bin folder. When i run a rebuild or build in Visual Studio it creates bin folder and required dll references by A, under B project.
But msbuild command does not work that way. It does not create bin and dlls under B. I investigate the problem, found some solutions like using dummy class user method to make msbuild copy references under bin. But it did not work too.
Project A -> Project B/bin/C Dlls ->Project C
Project C Dlls required by Project A.
What do i have to do to make msbuild command create bin folder under B project?
It looks like the circular dependency is still present. It has only been circumvented by going directly to the bin folder. This bypasses the safeguards that call out a circular dependency at build time.
As a general rule, if you need to go directly to the bin folder then there's a problem.
I suggest refactoring the projects to remove the circular dependency.
Related
I have the following (simplified) solution structure:
ProjectA
|- Content: myexe.exe with CopyIfNewer
ProjectB
|- ProjRef: ProjectA
ProjectC
|- ProjRef: ProjectB
When I run a build of ProjectC where ProjectA is built also (e.g., because ProjectA is not up-to-date, or because I clicked "Rebuild all") then myexe.exe is put into ProjectC's bin output folder. However, in any other case, myexe.exe is NOT in ProjectC's bin output folder.
Is this a known problem? Am I doing something wrong? How to fix this?
However, in any other case, myexe.exe is NOT in ProjectC's bin output
folder.
Is this a known problem? Am I doing something wrong? How to fix this?
Test
First, l guess that the first project is a ,net framework project or even the three projects are based on the framework. In my side, l created such three projects and cited the relationships you mentioned for the three projects.Exactly, when I modified the codes of Project C(A and B already built before), the file cannot copy into Project C as you wish. But when l just have two projects A,B(B project reference:A), it always copy the files of the first project A into B(whenever l choose Copy always or Copy if newer or build or rebuild the project B). Besides,I tested three projects which are based on Net Core or .Net Standard works without problems.
Conclusion
So the reason for this problem is pointed out that the intermediate project, project B, is not built(up-to-date Skips the build ), so the files of Project A could not be copied to the Project C as the transit station. (especially for non-sdk framework projects). l think it is a feature or issue in Project Reference in Visual Studio. or you could report it to DC Forum for a detailed explanation.
Solution
You can add such property to the csproj file of project B to break the latest check and ensure that it is always built. You can add this node under PropertyGroup both in Debug or Release
<DisableFastUpToDateCheck> true </DisableFastUpToDateCheck>
Hope it could help you.
Is it possible in MSBuild 4.0 and/or 4.5 to specify additional files to be treated as a manifest output of a project by its dependencies, and copied with the binary project output, whenever that is copied? Ideally, I want to create some files beside a .dll during build, and would like these files to stay in the same folder as the .dll whenever it is copied to a directory of a project depending on it.
If this is not clear, I am thinking of .pdb and documentation .xml files created by the C# compiler. These files treated specially: Whenever another project requests the .dll be copied locally into its binary directory, these files go with the .dll. Can I augment this set with my own special files?
This is not possible, and here is why. Actually, there is no concept of project output accessible externally between MSBuild projects. Rather, when a reference to a project is added, the SDK-provided build framework (based on MSBuild scripts) looks for a few specific files matching the name of the referenced DLL, and copies these files with the DLL itself into the current project output directory (assuming CopyLocal is set, which is probably true for a referenced project).
In framework v4.0, this is done by the task ResolveAssemblyReference which is called from an identically named target from the file %windir%\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets. The task looks for specially named files placed beside the target DLL, including its matchin PDB files and an XML documentation file. Other files are also discovered, as I infer from the decompiled source.
So nothing in a given project specifically marks these files as somehow "exported" from the project. The magic happens on the pulling side.
I have a solution that contains two projects:
- projectA has a nuget reference to ServiceStack ormlite
- projectB has a reference to projectA
When I build the solution the outdir for projectA contains all the assembly coming from nuget packages (4 assemblies), whereas the projectB only copies 2 of them. Obviously when I start it I get an FileNotFoundException.
I have already tried with no success to add private=true flag
I have seen many references to this problem and it gets very confused now about what is going on here (it seems that msbuild does not handle reference the way I think is the only thing I know:().
Any idea what could be done to have a reliable process to build my solution ?
The build will only copy to projectB's output folder the assemblies that are actually used by projectA and result in references in projectA's output assembly, regardless of which assemblies projectA references.
You can open projectA's assembly with Reflector or ildasm and see that of those 4 assemblies only 2 are actually used and referenced.
If the assemblies need to be there at runtime for projectB, add a reference to the NuGet package to projectB as well, or make sure they are copied. This post shows a general-purpose solution, but I haven't tried it.
Project A references Projects B. Project B references Project C. Project A does not reference Project C.
This builds fine locally. However, on the build server it errors out because Project A does not reference Project C.
Error:
error BC30009: Reference required to assembly 'ProjectC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' containing the implemented interface 'ProjectC.IFoo'. Add one to your project.
How can I catch this before committing?
Edit:
Here's more info on my issue: http://sstjean.blogspot.com/2006/11/msbuild-cant-find-secondary-references.html
Here are two things you can do as a best practice to ensure your projects are referenced correctly and MSBuild will be able to find your referenced projects correctly.
Use project references instead of referencing dll's. Create a folder called dependencies or libs and place any referenced dll's within this folder.
Check the build order and project dependencies tab for each project by right clicking project and selecting project build order. Ensure that every reference in your project is being built by that project.
MSBuild does not know what a .sln file is. MSBuild reads and parses the .sln file to determine the build order of projects. By having project references MSBuild will be able to traverse and build the projects in the correct order. See below link for more information.
This link also helps explain why you would see different behavior and how to catch it.
Visual Studio Integration (MSBuild)
Within Visual Studio, the solution file and project build ordering are controlled by Visual Studio itself. When building a solution with msbuild.exe on the command line, MSBuild parses the solution file and orders the project builds. In both cases the projects are built individually in dependency order, and project to project references are not traversed. In contrast, when individual projects are built with msbuild.exe, project to project references are traversed.
When building inside Visual Studio, the property $(BuildingInsideVisualStudio) is set to true. This can be used in your project or .targets files to cause the build to behave differently.
Go to your project references and right click Oracle.DataAccess then go to properties and in properties page make sure that specific version is false and copy to local is set to true.
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.