Import targets during build process with MSBuild - c++

I am using vcpkg as package manager with Visual Studio C++ project. I have created initial target to basically set up vcpkg (clone vcpkg repo and download vcpkg.exe):
<Target Name="EnsureVcpkgBuild" BeforeTargets="PrepareForBuild">
<Exec Command="git clone $(VcpkgRepo).git ..\packages\vcpkg" Condition="!Exists('..\packages\vcpkg\.git')" ContinueOnError="true" />
<Exec Command="git --git-dir=..\packages\vcpkg\.git --work-tree=..\packages\vcpkg pull --ff-only" Condition="Exists('..\packages\vcpkg\.git')" ContinueOnError="true" />
<Exec Command="..\packages\vcpkg\bootstrap-vcpkg.bat" Condition="!Exists('..\packages\vcpkg\vcpkg.exe')" ContinueOnError="true" />
<PropertyGroup>
<ErrorText>This project uses vcpkg that is missing on this computer. Manually download from $(VcpkgRepo) and place the contents in {0}. Or install git and add it to your path, for more information see https://git-scm.com. The missing file is {1}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\vcpkg\vcpkg.exe')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\vcpkg\', '..\packages\vcpkg\vcpkg.exe'))" />
<Error Condition="!Exists('..\packages\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\vcpkg\', '..\packages\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets'))" />
</Target>
In my project I am importing the vcpkg targets file:
<ImportGroup>
<Import Project="..\packages\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets" Condition="Exists('..\packages\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets')" />
</ImportGroup>
This setup ensures build works smoothly in Visual Studio without any additional work. However when working with CI/CD pipeline I have to first invoke EnsureVcpkgBuild first before trying to build the project. Can I set up this project in such way that I don't have to invoke EnsureVcpkgBuild and initiating build automatically sets up vcpkg and imports vcpkg.targets?

You can directly use nuget package to realize them all automatically.
What I think is that you wrote a target to download the reop project vcpkg into the local and then manually import the core target from the dowloadeded vcpkg project.
It could be done easily on the local area but on the cl pipeline, it is not suitable.
So use nuget could be more easier.
Just install the nuget package Vcpkg.Nuget into your c++ project.
All the import targets are in the nuget package and it could be imported into your project automatically with the installation of nuget.
When you are on the CI/CD pipeline, just add a nuget restore task to restore the nuget packages on the pipeline.

Related

Missing file NuGet.targets on existing project

The scenario is:
1. Created a NEW solution
2. ENABLED download missing packages
3. Add projects to solution that already exists and depends on nuget packages
4. Building the solution generates an error:
... The missing file is <solution folder>\.nuget\NuGet.targets.
Why? Have missing something?
I'm using Visual Studio 2017 Pro on Windows 10
All my searches answer about the scenario where create a new solution and adds a new project that depends on nuget package, that's ok, but when have an existing project, nothing.
<solution folder>\.nuget\NuGet.targets is a file that NuGet's Visual Studio extension used to add in Visual Studio 2010, 2012 and 2013 when you right click on the solution and select "Enable NuGet Package Restore". It would then add an import in all of your project files to import the targets file. I was recently investigating a customer issue and as part of that investigation I found it made the following changes. Near the top of the csproj, it adds something like this:
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
and near the end of the csproj it adds somthing like this:
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
So, the problem is that you're creating a new solution, but using existing project files that have been modified in this way. One option is to edit your csrpoj files and remove these changes. Another option is to create new projects, in addition to the new solution, and then copy all your code and content files.
The only disadvantage is if you build on a CI server and use packages.config, your build script needs to run nuget.exe restore, whereas projects that use NuGet.targets could just build the solution and msbuild would execute nuget restore as needed. One advantage of no longer using NuGet.targets is that restoring the whole solution is faster than restoring project by project. Visual Studio automatically restores packages on build, even in VS2010, VS2012 and VS2013, so personally I discourage the use of using this feature, even if you use those old versions of Visual Studio. The benefit of reducing your build script by one step is not worth the issues it brings, in my opinion.

.NET Core with NUnit test

I'm using .NET Core and am creating a unit test.
To do this, I'm running "dotnet new nunit -n tests" to create a project with the first class to test another project.
The problem is: I can run the simple code created with "dotnet test", but I can't code because I'm receiving 'could not be found NUnit' error.
PS.: I'm using Visual Studio Code (last version).
My .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
</ItemGroup>
</Project>
The error:
The type or namespace name 'NUnit' could not be found (are you missing a using directive or an assembly reference?)
I ran into this issue too and was perplexed by it. It turns out the problem is with the solution, not the dotnet new nunit project that was created.
The solution is auto-including the sub directory and attempting to build it as source. The directory can be excluded by right clicking the new test project in the solution and selecting "Exclude from Project". Rebuild and the errors go away.
I solved the problem using Visual Studio 2017 (not Visual Studio Code). It is better to architect a Microsoft solution.
EDIT: If you are using Visual Studio (complete version) you can see better the solution, projects and references.
If you are using Visual Studio Code and include new class or files, the reference is not added in you project file (.csproj) automatic. Maybe have another way to do that, but in the moment, I just use the complete version.

nuget package reference blue icon in visual studio 2017

For some reason in my console app, couple of the reference that I installed thru nuget shows the blue nuget icon. I can build my project locally, but not after I deploy my project to cloud. The error msg is complaining about not able to find these 2 references. Seems like I can't delete them either by right click(no delete option avaialble). Any idea?
nuget package reference blue icon in visual studio 2017
That because you are using the packagereference on the project types that are not .NET Core.
You can edit the .csproj file and check if it contains following ItemGroup:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
To resolve this issue, you can delete this PackageReference from your project file, then add those package with nuget package.
Besides, you should check if you have set the Default package management format to PackageReference. If yes, change it to packages.config, then add those two packages with nuget:
Hope this helps.
Happened to me in VS 2022.
Solved by deleting the bin and obj folders, which removed the reference with the blue icon. And after that reinstalled the NuGet packages, which added the references to the csproj file.
update-package -reinstall -project MyProjectName

The target "GatherAllFilesToPublish" does not exist in the project

I've checked that the same error occurred in the past with earlier vs .net versions but I am facing this issue in VS 2017 while trying to upgrade from VS Community 15.3.5 to 15.4.
I first installed using the web installer by choosing the options,
some how there were a couple of errors & the download + installation took over 9+ hours
visual studio was working and compiling project except that this had the problem 'The target "GatherAllFilesToPublish" does not exist in the project'.
Then I tried downloading the entire setup using "vs_community.exe --layout "C:\MyFolder" --lang en-US" which again took over 9 hours to finish download. Re-ran the setup choosing Repair, again the same issue.
Is any one aware of a quicker way to solve this above problem?
I had similar problem and it solved by changing csproj file:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
changed to
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" Condition="true" />
I had same issue (Visual Studio 2017).
Install - " MSBuild.Microsoft.VisualStudio.Web.targets " nuget package to visual studio. And then try to publish.
Just install the ASP.Net Web Deployment component for VS2017, it worked for me.
Similar issue occurred with me after I upgraded project from previous version to VS 2017. I had to make following changes in the csproj file.
Uncomment the following part of code from csproj file ( It was already present as comment, not sure why it did not change while upgrade automatically. If you do not have it, add below lines of code.)
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
</VSToolsPath>
</PropertyGroup>
Make sure below 3 imports are present in the csproj file. (These were also present, but if not, add manually)
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
And then I was able to publish the project.
I wonder what packages are changing these paths?
Mine is as follows:
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildProgramFiles32)\MSBuild\Microsoft\VisualStudio\v14.0</VSToolsPath>
changed to
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
same issue as this: https://stackoverflow.com/a/48545538/231821
I had this same problem, I updated Visual Studio 2017 to a newer version via the installer.
The installer never completed successfully. It completed with some errors which I just ignored so many of the components weren't installed which came after the components with errors. After I resolved the error components, the rest of the installation finally completed successfully and I could publish again with no problems.
I think some of the components which wasn't installed previously was older versions which was not compatible with the new update.
Try installing/updating your visual studio completely with no errors.

VS 2017 not discovering tests on .NET Core

can anyone help me get VS2017 to work with .NET Core test projects?
I tried creating both MSTest and xUnit unit test projects for .NET Core from the VS 2017 templates. Neither of them works in the test explorer (not discovered), however running dotnet test from the project folder works fine.
Steps to reproduce:
Create new project in VS 2017
Choose either the Unit Test Project (.NET Core) or xUnit Test Project (.NET Core) template
Implement some arbitrary unit test
Build the solution
Go to the text explorer and try to Run All
At this point the Output window should tell you that 0 test were discovered
.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
If I tried to create a MSTest unit test project from the template that targets .NET Framework (full, not .NET Core), it worked.
Any ideas?
In the end, the problem was solved by changing my system PATH env. variable from C:\Program Files\dotnet\ to C:\Progra~1\dotnet\, as answered in Can't get XUnit tests working with Visual Studio 2017 RC
Thanks to Alexey for suggesting it in the comments :)
I think I experienced same behavior. Try to build your solution so that VS can discover your tests. Otherwise please share you tests csproj file to ensure you reference correct packages. Mine is:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
UPDATE: I have played around a bit and it looks like VS cannot find the tests without <OutputType>Exe</OutputType>
UPDATE 2: Try also add following to csproj as I see VS adds in in some cases.
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
I hit this issue with VS 2017 not discovering MSTest unit tests on .NET Core.
The Tests output only reported that it had discovered zero tests.
On running dotnet test MyProject.csproj -t in a command prompt, it advised that I did not have the correct .NET Core runtime installed to match the project's RuntimeFrameworkVersion.
Installing the latest VS 2017 update and .NET Core runtime resolved the issue.
I had the same issue. I resolved it by installing the "Microsoft.NET.Test.Sdk" package from nuget.
I had the same issue after migration from project.json to csproj.
And resolved it by removing net451 target framework and leave only netcoreapp1.1. Now it's works perfect and discover every time.
Of course if you need many framework targets you shouldn't do it, just use CLI to test them...
It may due to inconsistent project settings for Processor Architecture. The Test project target must match the test default Processor Architecture.
Check https://stackoverflow.com/a/47454276/2700303
I also had this issue and it was remedied by ensuring my project and test project had the same target framework version in the .csproj file
<TargetFramework>netcoreapp1.0</TargetFramework>
Also make sure you don't have mixed PackageReference versions in the *.csproj files when having multiple test projects and the same output directory and also update the packages of test project especially MSTest.TestAdapter as well as MSTest.TestFramework