I'm working in a project for a customer where one solutions has 3 projects.
Project A is the base, then project B depends on A, and project C depends on B. By the way, project C is the application, A and B are class libraries.
Usually, I can make a change in project A without the need of manually recompile B and C because Visual Studio does it automatically for me.
However, in this environment (after downloading the solution via Ankh SVN), the dependencies are somewhat not recognized when executing. I'm forced to manually recompile the dominant projects of the dependency hierarchy.
Why is this happening? and how to solve it?
Thanks!
Make sure you added the references of project B and project C as a project and you didn't add the project output as an assembly reference.
Related
I'm trying to understand why removing a project reference prevents my build from downloading all the NuGet packages it needs. This is with Visual Studio 2019
Application A (.NET 5) holds a project reference to Assembly B.
Assembly B uses a NuGet package C.
When the build starts, NuGet Package C get downloaded automatically.
This is all vanilla expected, .NET stuff.
But then I realized that A does not actually use any B-specific types. B is a Prism Module that only loads dynamically if the user has a license for it and clicks a button. So A doesn't even always load "B".
So I removed A's project reference to B. I don't want some future developer to accidentally think they can start referring to types in B. (We don't ship all modules all the time). Technically now, there is no project in the solution that holds a reference to B. But it's still part of the build. I did set up the build dependencies so that B would still build before A but there's no longer a project reference..
Then I did a clean build. Visual Studio said it completed successfully. And I see Assembly B got built. But the build process did NOT retrieve NuGet package C (that B depends on). Testing has revealed it will not retrieve C unless application A actually holds a project reference to B.
Is there some way around this? If I'm building all assemblies, why would MSBuild not download all assemblies dependent NuGet packages. Is there some setting I can change to make it happen.
Answering my own question in case anyone else ever has this problem:
I asked this question of Microsoft. They said that this behavior is by design: If a DLL-generating assembly ("B") uses a NuGet package, then the only way that package will be downloaded at build time is if an assembly that generates an EXE has a project reference to B. Merely having a build dependency is not enough.
No explanation as to why. I still think the behavior should be different for reasons I mentioned in the question and comments above. They said it is a question for the .NET team and referred it to them. I finally got a reply that said, I can make this behavior happen by adding an attribute (named CopyLocalLockFileAssemblies) to my Assembly B's project file.
So I did. Added this:
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
And it worked. With this attribute set to true, an assembly that requires a NuGet package will get that assembly in the output folder regardless of whether or not anyone has a project reference to it.
(One could argue that this is a RTFM sort of question. But learning MSBuild and its ins-and-outs is one of many things I "eventually need to do" on my plate)
I'm using visual studio 2010, and its a C++ solution with multiple projects. I have project A which has reference to project B(Properties->Common Properties->Framework and References). Project C references project A.
Now the build order is B->A->C. C now indirectly references B, is it required that we should manually add Project B as reference to project C?
I want to make sure that when project C is built project B should automatically be built if any changes were made to it and it is not rebuilt yet.
Building your Solution should always build Projects that have changes.
A circular dependency is created if you try to make B->A->C->B. You can have circular dependencies in VS but the build order must be managed manually. See this post.
If a Project references an assembly and not the Project that builds that assembly then VS does not build the dependent Project. If the Project references the Project that builds the dependent assembly then any changes to the dependent Project are built before the target Project. This is the default behavior in VS. That behavior can be changed or managed using the 'Build Dependency' dialog.
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.
I have a big VS2008 solution containing >30 VS projects with legacy code. One of these projects (let's call it A) generates a header file, which is needed by a few other projects (for example B). When I go to "Project Dependencies" of the VS solution, I can check project A for project B's dependencies - but VS includes in the project B's linker command line options an additional argument for project A's lib ("A.lib"). Unfortunately, since project A does not create a lib file, this project B will never find one and cannot be built.
Is there a feasible solution for my problem?
Thanks in advance!
Cheers,
Chris
You should set Ignore Import Library in project A.
This option specifies that the (import) library generated by this configuration should not be imported into the dependent projects.
We have a visual studio package (VS Package) that references a class library project (Project A). Project A in turn references another class library project (Project B).
So the dependency structure looks like this: VS Package > Project A > Project B
All projects exist inside the same solution and the dependencies have been set up as proper project references.
If I build the package in visual studio and look in the bin/Debug folder all necessary assemblies are there including Project B's. However when the package is deployed, only Project A's assemblies are present and Project B's are missing. How do I tell visual studio to include the indirect dependency of Project B in the package?
This MSDN document suggests that "By default in a multi-project solution, if a project that outputs to a VSIX package includes a reference to another project in the same solution, it includes the dependencies of that project."
However I am finding that this is simply not the case.
My question is very similar to this one except that I am having trouble with the main project assembly and not the localization satellite assemblies. The answer in this other post does not work for me because it seems to only work for satellite assemblies.
Is there some other Output Group that I can specify to direct the package to include indirect dependencies as well?
Thanks for looking.
The simplest thing to do in this particular case is reference Project B from the VSPackage project and set the "Reference Output Assembly" property to False to avoid introducing a compile-time dependency.
I had a similar problem: My VS Package project referenced another VS package project (~Project A) which in turn referenced a bunch of other projects (~Project B) containing the meat of our extension.
Inspired by this answer: VSIX package doesn't include localized resources of referenced assembly, I added 'BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;GetCopyToOutputDirectoryItems;SatelliteDllsProjectOutputGroup' to the Output Groups Included in VSIX property of the reference from VS Package to Project A.
This had the effect of dropping all the dependency DLLs in the ...\Debug\ folder for my VS Project, but they still didn't get included in the VSIX.
Finally I went and added the BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;GetCopyToOutputDirectoryItems;SatelliteDllsProjectOutputGroup flags to all the references from my Project A to each of my Project Bs - then they all got included in the VSIX.
(BTW this is with with Visual Studio 2013, but it doesn't seem to have change much since 2010)