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
Related
I have a Visual Studio solution with the project I am working on (main project). The solution references a different project that main project requires as a dependency (dependency project).
The solution and the main project are located in one directory:
/mycode/main_project/main_project.sln
/mycode/main_project/main_project.csproj
The dependency project is located in a different directory:
/mycode/dependency_project/dependency_project.csproj
Both of these projects are under source control. I want to create some kind of configuration file for main project that is not under source control, so that another developer could clone both projects wherever they want and simply edit a non-source-controlled configuration file to allow the main project's solution to locate dependency project.
Currently, main solution locates dependency project using a relative path:
../dependency_project/dependency_project.csproj
If I enforce that all developers should clone these two projects to the same directory, the main solution will successfully link to the dependency project and everything will be happy. However, I would prefer that another developer can place the dependency project wherever they want.
Does Visual Studio 2019 Community support any kind of solution configuration file which could be kept ignored by version control and used to resolve the path to the dependency project?
Solution files are very primitive and do not offer such a dynamic functionality. However, if you don't need dependency_project to show up in the IDE, you can still reference it from main_project.csproj and that does give you more options. It should still build fine even if the project doesn't show up in Solution Explorer.
For example, you could reference it through an environment variable, with a default expected path if that variable isn't set:
<PropertyGroup>
<DependencyProjectPath Condition=" '$(DependencyProjectPath)' == ''>../dependency_project/dependency_project.csproj</DependencyProjectPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="$(DependencyProjectPath)" />
</ItemGroup>
If you set the DependencyProjectPath environment variable before opening the solution (because VS inherits the environment variables from where it was launched), it will override the default setting here (based on the Condition attribute).
I have a proof-of-concept solution that has a .NET Standard project in it. I use Paket to manage my nuget dependencies. I am able to use paket add and dotnet restore, per these instructions, to add a nuget dependency to that project. When I reopen my solution, I see that a paket.references file has been added to that project, and that a "NuGet" section has been added under the project's "Dependencies" section in "Solution Explorer".
I'm curious, how does VS2017 know what dependencies to list that "NuGet" section?
From the instructions I linked to above:
In contrast to traditional .NET projects Paket will not add assembly
references to your project files. Instead it will only generate a
single line:
<Import Project="..\..\.paket\Paket.Restore.targets" />
This hook tells the .NET SDK to restore packages via Paket's restore
mechanism. A nice benefit is that your project files are now much
cleaner and don't contain many assembly references.
I'm sure I'm missing something, but I don't see anything in Paket.Restore.targets that would tell Visual Studio where to look to find the dependency chain of the nuget package I added to the project. There are no direct references to any dependencies mentioned in the project file.
For context, I have a repo where I'm trying to add a .NET Standard project to a solution that is full of .NET Framework projects. I'm running into an issue where paket add seems to correctly create a paket.references file for the new project, but dotnet restore doesn't seem to be causing the project references to update, resulting in my project not having a reference to the nuget dependency I'm trying to have it reference. I'm having trouble creating a reproducible example (my proof-of-concept seems to be working fine), so I'm trying to better understand how this infrastructure works to help with debugging.
MSDN docs Visual Studio Integration (MSBuild) state:
Building Solutions
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.
With my Visual Studio 2010, when building a .sln file with MSBuild from the command line, project to project references are all built, regardless whether they occur in the solution.
What did I miss here? Or are the docs plain wrong?
You are correct that msbuild.exe will sort out all project references whether or not they are part of the solution in contrast to building within Visual Studio 2010/2012/2013/2015 (and possibly later versions) where you will get a build failure if a referenced project is not part of the solution or built beforehand.
In short, yes, the documentation seems a bit off.
You can ignore the build of project to project reference by running msbuild Solution.sln /t:ProjectName /p:BuildProjectReferences=false this explain the sentence in msdn.
How to configure TeamCity to build a solution with 2 projects?
I have configured TeamCity to build my solution which has 1 project which is chosen as Startup Project and it builds fine.
I configured it by adding a new Build Step with Runner Type of "Visual Studio (sln)" from its WebUI.
I added a new class library project and added a reference to it from the first project and it builds fine locally.
The .csproj file of the first project now contains this:
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj">
<Project>{00E69E26-2576-4B9A-9180-CB1877B1D951}</Project>
<Name>ClassLibrary1</Name>
</ProjectReference>
</ItemGroup>
I checked in the code and teamcity fails to build!
error CS0246: The type or namespace name 'ClassLibrary1' could not be found (are you missing a using directive or an assembly reference?)
TeamCity seems to only build the startup project not the ClassLibrary1 although it's referenced.
How could I configure it to build my solution?
Would this be possible using the WebUI or I should be writing e.g. MSBuild scripts?
Thanks,
Team City handles .sln files, so you should not have any problems with mutliple projects.
Make Team City build the .sln files, not a csproj.
If it's already ok, check your reference to see if it points to the project within the solution or if it refers to the assembly file (might cause problem if you change your build configuration for example)
Your reference should look like this
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj">
<Project>{some guid identifying your project}</Project>
<Name>ClassLibrary1</Name>
</ProjectReference>
To have this result, the reference should be made by right clicking a project on solution explorer, choose add reference and go to the Project section
Actually, the problem was TeamCity was caching because and the solution was to check the below check box from the Version Control Settings:
Agent checkout: Enforce overwrite all files
The reason it was caching was that I'm using the Checkout mode of "Automatically on server" which means it will cache: http://confluence.jetbrains.net/display/TCD65/VCS+Checkout+Mode
If both project Alpha and project Beta are C# projects, we can set that Beta depends on Alpha and this results to following build order: 1) Alpha; 2) Beta
If project Alpha is C++ project, we cannot add reference from project Alpha to Beta because Visual Studio 2010 does not allow this. Actually we can hack csproj file with notepad, but it doesn't help. Bu we can right click on solution, choose Project Dependencies and say that Beta depends on Alpha.
Problem: MSBuild does not honor dependencies set in sln file and builds projects in wrong order - 1) Beta; 2) Alpha. Note, that Visual Studio honors build order.
How we can set build order for MSBuild between C# and C++ projects within same solution?
Try adding your C++ project reference to the C# project after cleaning the solution. This works for me, although I stumbled on this "workaround" by pure chance.
To me it looks as if Visual Studio is checking the build product of the referenced project, and when it notices the incompatibility it will refuse to add the reference. If, however, the build product is not around to check (because you cleaned the solution), Visual Studio happily adds the reference.
I tested the resulting solution both in Visual Studio and on our TFS build server (which AFAIK uses MSBuild) and build dependencies were evaluated correctly in both cases.
In your question you also mention that manually editing the .csproj file didn't help. I cannot confirm this. I was able to add the following reference and again got a positive build result:
<ProjectReference Include="..\Foo\Foo.vcxproj">
<Name>Foo</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<Private>False</Private>
</ProjectReference>
I am adding the ReferenceOutputAssembly element because this blogs.msdn.com article suggests it. In my experience, though, the build also works without the element. The article is still worth reading because it explains why MSBuild does not honor dependencies defined in the solution.
For completeness sake: I am running Visual Studio 2010, Version 10.0.40219.1 SP1Rel.