Linking Libraries with NuGet Packages as dependencies in Visual Studio - c++

I have a Console Project LinkExample that contains a main.cpp.
#include <Library/Logger.hpp>
int main()
{
WriteSomething();
return 0;
}
The LinkExample links a static Library Project named Library. Library.Lib is linked correctly.
Library contains a Logger.hpp
#pragma once
void WriteSomething();
Logger.cpp
#include <boost/log/trivial.hpp>
#include <Library/Logger.hpp>
void WriteSomething()
{
BOOST_LOG_TRIVIAL(trace) << "Trace";
}
The NuGet Packages are:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="boost" version="1.63.0.0" targetFramework="native" />
<package id="boost_log-vc140" version="1.63.0.0" targetFramework="native" />
</packages>
LinkExample does not build and shows the error LNK1104 for file libboost_log-vc140-mt-gd-1_63.lib.
When linking statically I would want this library to be baked into Library, why does this not happen and how can I fix that?
I am aware that I could add packages to LinkExample but that is not a long term solution.
Adding packages until the solution runs would include these packages.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="boost" version="1.63.0.0" targetFramework="native" />
<package id="boost_date_time-vc140" version="1.63.0.0" targetFramework="native" />
<package id="boost_filesystem-vc140" version="1.63.0.0" targetFramework="native" />
<package id="boost_log-vc140" version="1.63.0.0" targetFramework="native" />
<package id="boost_system-vc140" version="1.63.0.0" targetFramework="native" />
<package id="boost_thread-vc140" version="1.63.0.0" targetFramework="native" />
</packages>
In a larger Project things started falling apart with this approach after switching boost to dynamic linking.
How do I get rid of my root problem that the lib files are linked by my customer library?
Note that the "Link Library Dependencies" setting does nothing here, using this setting would require a project setup that is incompatible with NuGet.

This is the default behavior of Visual studio. We could not use the NuGet Packages as dependencies directly in the LinkExample project, which provide by the linked customer library. The Visual studio only load the files of static Library Project when we build the LinkExample project, those dependencies of static Library Project would not be loaded. So I agree with Jeroen Heier, if you want to use those packages to LinkExample project, you need to add packages to LinkExample.

Related

Dependent project cannot see headers from a library in refferences in Visual Studio

I am learning how to make a static library. I started with windows and Visual Studio.
The directory structure looks like this:
- MyLibraryProject
- include
- MyLibraryProject
- MyLibraryHeader.h
- src
- MyLibrarySource.cpp
- build
- MyLibraryProject.vcxproj
- MyDependentProject
- main.cpp
- MyDependentProject.vcxproj
MyLibraryProject.vcxproj has the following settings:
Setting
Value
Configuration type
Static library (.lib)
Additional Include Directories
$(MSBuildThisFileDirectory)../include/MyLibraryProject
MyDependentProject.vcxproj has no special settings, except I added MyLibraryProject onto refferences, the image features actual names I used:
If I use relative paths in main.cpp, I can build the project - the static linking works just fine and it runs:
#include "../MyLibraryProject/include/MyLibraryProject/MyLibraryHeader.h"
However, I want to include the headers like this:
// fatal error C1083: Cannot open include file: 'MyLibraryProject/MyLibraryHeader.h': No such file or directory
#include <MyLibraryProject/MyLibraryHeader.h>
And that just does not work. I also tried to use property sheet but couldn't get that to work either. I've been searching the internet, but generally found claims that if you add a reference, both headers and static libs will work.
Here's the full repository, if you're willing to take a look. Or ask in the comments if there's information missing.
Project references do not provide the dependent project with any information about headers. The most flexible way to do this instead (in Visual Studio) are property sheets. I created a file MyLibraryProject/build/MyLibraryProjectDependency.props:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
And I added it to MyDependentProject.vcxproj in Property explorer in Visual Studio. This solved the issues and headers are now seen on the path I want them.

Microsoft.CodeAnalysis.Metrics was unintentionally added to nupkg dependencies

I added a NuGet packages 'Microsoft.CodeAnalysis.Metrics' (v2.9.8) to my project to measure code metrics.
Just I wanted to measure code metrics, I don't mean to write any code depends the library.
Then I created nupkg with nuspec below,
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<!--
<licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
<projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
<iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<releaseNotes>First release of this library.</releaseNotes>
<copyright>Copyright (c) 2018 My Company.</copyright>
<tags></tags>
<dependencies>
<group targetFramework=".NETFramework4.5.2" />
</dependencies>
</metadata>
</package>
Next I created with a command NuGet.exe pack MyCompany.MyProject.csproj, and a nupkg generated.
After that I checked the nupec included in the generated nupkg.
The nuspec is below:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>MyCompany.MyProject</id>
<version>1.0.0</version>
<title>MyCompany.MyProject</title>
<authors>My Company.</authors>
<owners>My Company.</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MyCompany.MyProject is a example.</description>
<releaseNotes>First release of this library.</releaseNotes>
<copyright>Copyright (c) 2018 My Company.</copyright>
<dependencies>
<dependency id="Microsoft.CodeAnalysis.Metrics" version="2.9.8" />
</dependencies>
</metadata>
</package>
There was a dependency to Microsoft.CodeAnalysis.Metrics unintentionally.
I also added a NuGet package 'Microsoft.CodeAnalysis.FxCopAnalyzers' as well, but it wouldn't apprear in the generated nuspec. I don't know the difference.
I would like to avoid to be added any dependency libraries to nupkg dependencies, except libraries which my project depends on.
How can I make it as I intend.
Is it a problem of the 'Microsoft.CodeAnalysis.Metrics'? Should I report to the developers?

Need guidance on packaging QT Desktop Application into AppX format using Visual Studio 17

I am trying to create an appx/appxupload package for my QT GUI application so that it can be published to the Windows Store. Here are the list of steps I followed to generate an appx package:
Generate a Visual Studio project file using my QT .pro file by using the qmake -tp vc command in the directory containing my .pro file. I have used the x86 msvc-2017 kit in QT
Opened the .vcproj file using Visual Studio 2017 ,Version 15.9.10 and built the project to check for any errors.
Added a new project Windows Application Packaging Project (Visual C++) to the same Visual Studio solution.
Added my QT project (now converted to Visual Studio project) as a reference to Applications in my new Packaging project
Added all the Visual Assets, app name and other configuration settings in the Designer mode and then built the project
Package the application to upload to Windows Store
When, I try to install and run the application, I get an error saying : This application failed to start because it could not find or load the Qt platform plugin "windows" in "".. All the QT plugins are present in the installation folder, however my application exe file is present inside an another folder in the installation directory like AppName\AppName.exe. If I copy the AppName.exe outside the AppName folder and run, the app runs fine.
I went through the various xml files and I see under Application section, Executable = "AppName\AppName.exe" instead of Executable = AppName.exe. I believe there is a configuration setting where one can configure the Application target path. If the exe file is at the same level as that of all the other QT dll's, the app will run fine without errors.
Can someone please help resolve this issue?
Thanks
The Package.appxmanifest generated by Visual Studio
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
<Identity Name="CybernetyxTechnikPvt.Ltd.AirMindThinker" Publisher="CN=FD00F14F-4E0A-4328-8B66-60A5777EDBFE" Version="1.0.24.0" />
<Properties>
<DisplayName>AirMind Thinker</DisplayName>
<PublisherDisplayName>Cybernetyx Technik Pvt. Ltd.</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements DisplayName="AirMind Thinker" Description="AirMind Thinker Application" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" Square310x310Logo="Images\LargeTile.png" Square71x71Logo="Images\SmallTile.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
This is the AppxManifest.xml generated in the output folder (bin/x86/Release/)
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap build" xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build">
<!--
THIS PACKAGE MANIFEST FILE IS GENERATED BY THE BUILD PROCESS.
Changes to this file will be lost when it is regenerated. To correct errors in this file, edit the source .appxmanifest file.
For more information on package manifest files, see http://go.microsoft.com/fwlink/?LinkID=241727
-->
<Identity Name="CybernetyxTechnikPvt.Ltd.AirMindThinker" Publisher="CN=FD00F14F-4E0A-4328-8B66-60A5777EDBFE" Version="1.0.24.0" ProcessorArchitecture="x86" />
<Properties>
<DisplayName>AirMind Thinker</DisplayName>
<PublisherDisplayName>Cybernetyx Technik Pvt. Ltd.</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.14393.0" MaxVersionTested="10.0.17763.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.17763.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.26905.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
<Resources>
<Resource Language="EN-US" />
</Resources>
<Applications>
<Application Id="App" Executable="AirMindThinker\AirMindThinker.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="AirMind Thinker" Description="AirMind Thinker Application" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" Square310x310Logo="Images\LargeTile.png" Square71x71Logo="Images\SmallTile.png"></uap:DefaultTile>
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
<build:Metadata>
<build:Item Name="Microsoft.Build.DesktopBridge.Tasks.dll" Version="4.6.30319.200" />
<build:Item Name="TargetFrameworkMoniker" Value=".NETCore,Version=v5.0" />
<build:Item Name="VisualStudio" Version="15.0" />
<build:Item Name="VisualStudioEdition" Value="Microsoft Visual Studio Community 2017" />
<build:Item Name="OperatingSystem" Version="10.0.18362.1 (WinBuild.160101.0800)" />
<build:Item Name="Microsoft.Build.AppxPackage.dll" Version="15.0.28307.104" />
<build:Item Name="ProjectGUID" Value="e995a5ab-e99d-4e1c-864d-a5fbbfc73ceb" />
<build:Item Name="MakePri.exe" Version="10.0.17763.132 (WinBuild.160101.0800)" />
</build:Metadata>
</Package>

Generation error: Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0 " or one of its dependencies

I'm getting the following error seemingly randomly when I try generate my .feature files.
Occasionally I change or alter my feature file, and this error crops up out of nowhere:
#error Generation error: Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
I have absolutely no idea how to solve this - I have tried adding a reference to the assembly, changing versions of SpecFlow / NUnit but nothing seems to work.
Erasing my copy of the project and pulling it from source control works initially but then it happens again.
Here is a full list of my installed packages:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net461" />
<package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net461" />
<package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net461" />
<package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
<package id="NUnit" version="3.0.0" targetFramework="net461" />
<package id="NUnit3TestAdapter" version="3.9.0" targetFramework="net461" />
<package id="SpecFlow" version="2.2.1" targetFramework="net461" />
<package id="SpecFlow.NUnit" version="2.2.1" targetFramework="net461" />
<package id="System.ComponentModel.EventBasedAsync" version="4.0.11" targetFramework="net461" />
<package id="System.Dynamic.Runtime" version="4.0.0" targetFramework="net461" />
<package id="System.Linq.Queryable" version="4.0.0" targetFramework="net461" />
<package id="System.Net.Requests" version="4.0.11" targetFramework="net461" />
<package id="System.Spatial" version="5.8.2" targetFramework="net461" />
<package id="WindowsAzure.Storage" version="8.6.0" targetFramework="net461" />
</packages>
I'm running Visual Studio Community 17 (15.5.2), .NET 4.7.02556 and the SpecFlow extension version 2017.1.10
What sometimes works for me is deleting the packages folder from the solution path, then restore nuget packages in solution and regenerate the feature files.
Sometimes this is not enough, and you also have to delete the visual studio cache.
Which is located: %LOCALAPPDATA%/Microsoft/Visual Studio/<your VS version>/ComponentModelCache
This is a known issue, which we couldn't yet reproduce and fix.
GitHub Issue: https://github.com/techtalk/SpecFlow/issues/857
It's a Microsoft package issue. This solution worked for me. Issue disappeared and now builds successfully.
In your Azure Build Pipeline > NuGet tool installer step, change Version of NuGet.exe to install to a newer version, like 5.4.0.
Check Nuget's latest ReleasedAndBlessed version at https://dist.nuget.org/tools.json.
The fix for me was to remove the existing .feature.cs file(s) and then regenerate them.
I'm using Visual Studio 2017 15.5.1 and the following SpecFlow versions:
SpecFlow Version:2.2.0.0
SpecFlow Generator Version:2.2.0.0
The followin github thread, gave me the clues:
Visual Studio 2017 Generation error: Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0
Updating on the latest Visual Studio version resolve this issue for me.
OS: macOS 10.15.1

How to add C++ library in a .NET Core project

How is the way to add a C++ Library in a .NET Core project (Class Library). I tried creating a nuget package but doesn't work. I got this error:
An unhandled exception of type 'System.DllNotFoundException' occurred in "NameOfDll.dll"
When I add the nuget package the project.json add the following reference:
"dependencies": {
"Core": "1.0.0-*",
"NETStandard.Library": "1.6.0",
"NameOfDll.dll": "1.0.0"
},
dependencies attribute in project.json specifies package dependencies, because of this NuGet handles NameOfDll.dll as a package ID, but not as a dll name.
To add native C++ dlls into you NuGet package for .xproj library you should do the following steps:
Put your NameOfDll.dll in \lib directory near MyClassLibrary.xproj
Open project.json file and add there:
"packOptions": {
"files" : {
"includeFiles" : "lib/NameOfDll.dll"
}
}
Execute dotnet pack
NameOfDll.dll will be included into NuGet package under the path lib\NameOfDll.dll.
To add native C++ dlls into your NuGet package for .csproj library you should do the following steps:
I assume you have managed project with name MyClassLibrary.csproj.
Create new NuGet package for you class library with nuget spec command.
Create \lib, \build, \content and \tools directories near MyClassLibrary.nuspec.
Copy all your native dlls into the \build folder.
Change extension of copied native dlls to .native.
Create MyClassLibrary.targets with the following content inside \build folder:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<AvailableItemName Include="NativeBinary" />
</ItemGroup>
<ItemGroup>
<NativeBinary Include="$(MSBuildThisFileDirectory)*">
<TargetPath></TargetPath>
</NativeBinary>
</ItemGroup>
<PropertyGroup>
<PrepareForRunDependsOn>
$(PrepareForRunDependsOn);
CopyNativeBinaries
</PrepareForRunDependsOn>
</PropertyGroup>
<Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory">
<Copy SourceFiles="#(NativeBinary)"
DestinationFiles="#(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')"
Condition="'%(Extension)'=='.native'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
<Copy SourceFiles="#(NativeBinary)"
DestinationFiles="#(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')"
Condition="'%(Extension)'!='.native'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
</Target>
</Project>
Hint: The .targets content is taken from this question.
The above .targets file will be injected on an installation of the NuGet package into the target project file.
Add the following lines into your MyClassLibrary.nuspec:
<files>
<file src="lib\" target="lib" />
<file src="tools\" target="tools" />
<file src="content\" target="content" />
<file src="build\" target="build" />
</files>
Execute nuget pack MyClassLibrary.csproj to build your NuGet package.
Here is a one-click way to do it in .net core 2. I used it in my website and it works.
Right click your project in Solution Explorer, select Add->Existing Item, browse and choose your dll (select show all extensions). Then your dll will appear in Solution explorer.
In the Solution Explorer, right-click your dll -> Properties. Set build action: Content, and Copy to Output Directory: Copy if newer (or always copy).
It's done. Use your dll in your code staightforward like this:
[DllImport("my_dll.dll", CallingConvention = CallingConvention.Cdecl)]