Linker errors when consuming gRPC C++ on release configuration - c++

I've compiled the grpc library from source code using the official instructions on github.
I've used cmake to invoke MSVC v142 build tools(Visual Studio 2019), and generated two build configurations one for Release, and one for Debug.
From the build artifacts, and from the include files of the gRPC library, I've created a C++ NuGet package. That NuGet package uses both the Release as well as the Debug build artifacts(and of course places them in a designated folder for each configuration type).
I've created some "Hello World" app that consumes the gRPC library on Windows, via the NuGet package that I've built. (This is just a standard example the can be found on gRPC official examples, nothing new was added).
On Debug build of the "Hello World" app, everything works just fine - compilation, linking, execution and debugging, but when I switch to compile the project on Release, I have 7 linker errors related to missing functions definitions.
The instruction of how to build gRPC from source code was taken from here: "https://github.com/grpc/grpc/blob/master/BUILDING.md".
I've searched where were those functions implemented back on the gRPC source code, and found that it's in the 'grpc++' project, which being compiled to be 'grpc++.lib'. I've checked that this file does get included in my nuget package, in the correct configuration(Release) and architecture(x64).
I've checked that I did took the correct configuration and architecture as an input for the NuGet package, and even tried to link against those binaries directly without using the NuGet package that I've created.
This is the linker output when building with Release, x64:
1>------ Build started: Project: HelloGrpc++NuGet, Configuration: Release x64 ------
1>HelloWorldServer.cc
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "class std::shared_ptr<class grpc::ServerCredentials> __cdecl grpc::InsecureServerCredentials(void)" (?InsecureServerCredentials#grpc##YA?AV?$shared_ptr#VServerCredentials#grpc###std##XZ)
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "public: __cdecl grpc::ServerBuilder::ServerBuilder(void)" (??0ServerBuilder#grpc##QEAA#XZ)
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "public: virtual __cdecl grpc::ServerBuilder::~ServerBuilder(void)" (??1ServerBuilder#grpc##UEAA#XZ)
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "public: virtual class std::unique_ptr<class grpc::Server,struct std::default_delete<class grpc::Server> > __cdecl grpc::ServerBuilder::BuildAndStart(void)" (?BuildAndStart#ServerBuilder#grpc##UEAA?AV?$unique_ptr#VServer#grpc##U?$default_delete#VServer#grpc###std###std##XZ)
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "public: class grpc::ServerBuilder & __cdecl grpc::ServerBuilder::RegisterService(class grpc::Service *)" (?RegisterService#ServerBuilder#grpc##QEAAAEAV12#PEAVService#2##Z)
1>HelloWorldServer.obj : error LNK2001: unresolved external symbol "public: class grpc::ServerBuilder & __cdecl grpc::ServerBuilder::AddListeningPort(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::shared_ptr<class grpc::ServerCredentials>,int *)" (?AddListeningPort#ServerBuilder#grpc##QEAAAEAV12#AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##V?$shared_ptr#VServerCredentials#grpc###4#PEAH#Z)
1>D:\Users\abiton\Desktop\grpcsandbox\HelloGrpc++NuGet\bin\x64\Release\HelloGrpc++NuGet.exe : fatal error LNK1120: 6 unresolved externals
1>Done building project "HelloGrpc++NuGet.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
This is the executable code that uses the gRPC C++ library(Standard example, nothing was added by me):
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "src/server/helloworld.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloReply;
class GreeterServiceImpl final : public helloworld::Greeter::Service
{
Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* response) override
{
response->set_message("Hello from GRPC Server !");
return Status::OK;
}
};
int main(int argc, char** argv)
{
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
return 0;
}
These are relative paths for additional include directories added to my sample project:
grpc\include
grpc\third_party\protobuf\src
These are relative paths for the build artifacts:
grpc\.build\Release
grpc\.build\third_party\cares\cares\lib\Release
grpc\.build\third_party\protobuf\Release
grpc\.build\third_party\zlib\Release
And these are the linker inputs:
address_sorting.lib
cares.lib
gpr.lib
grpc.lib
grpc++.lib
grpc++_unsecure.lib
libprotobuf.lib
zlib.lib
Any help will be appreciated !

Related

LNK2019 error when using a library installed with vcpkg

I have installed libraries with vcpkg using the correct triplet :
C:\Users\***>vcpkg list libnoise
libnoise:x64-windows 1.0.0 A general-purpose library that generates three-d...
Then I have executed the following command :
C:\Users\***>vcpkg integrate install
Applied user-wide integration for this vcpkg root.
All MSBuild C++ projects can now #include any installed libraries.
Linking will be handled automatically.
Installing new libraries will make them instantly available.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=C:/Windows/vcpkg/scripts/buildsystems/vcpkg.cmake"
But in my Visual Studio 2019 project, with an x64 project, only the headers have been successfully integrated :
#include <noise/noise.h> // The header is found as well as the definition of noise::module::Perlin
int main()
{
noise::module::Perlin noise; // The implementation is not found
}
When trying to compile this, I get :
1>------ Build started: Project: Mayak, Configuration: Debug x64 ------
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl noise::module::Perlin::Perlin(void)" (__imp_??0Perlin#module#noise##QEAA#XZ) referenced in function main
1>NoiseVideoGenerator.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __cdecl noise::module::Perlin::Perlin(void)" (__imp_??0Perlin#module#noise##QEAA#XZ)
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl noise::module::Perlin::~Perlin(void)" (__imp_??1Perlin#module#noise##UEAA#XZ) referenced in function main
1>NoiseVideoGenerator.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl noise::module::Perlin::~Perlin(void)" (__imp_??1Perlin#module#noise##UEAA#XZ)
1>C:\Users\sylva\source\repos\Mayak\x64\Debug\Mayak.exe : fatal error LNK1120: 2 unresolved externals
1>Done building project "Mayak.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
On a side note, I have looked for the name of the .lib files of the noise library and tried to add them in the Linker > Input properties, it still doesn't work.
What did I do wrong ?
To enable AutoLink, select your current project and go to properties. (Alt-Enter) Make sure you edit the right configuration. Then go to Configuration Properties -> vcpkg and make sure AutoLink is enabled.
It has been fixed by the developers, on GitHub : https://github.com/microsoft/vcpkg/issues/14127

Unresolved externals when compiling unit tests for Visual C++ 2012

I want to create unit tests for a Visual C++ project. I tried following these MSDN instructions. I've found pages where they differentiate between unmanaged/mixed/pure code, but I don't fully understand those concepts. My code doesn't use .NET and would likely compile under MinGW with a few code adjustments.
My main project builds an executable, so I followed the steps under To reference exported functions from the test project. For starters I got different project options:
I went with Native Unit Test Project. I added a reference to my main project and I set Include Directories to $(SolutionDir)\Cubes;$(IncludePath). I wrote my code and got this when compiling:
1>Creating library C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.lib and object C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.exp
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Room::Room(void)" (??0Room##QAE#XZ) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Layout::Layout(class Room *,int)" (??0Layout##QAE#PAVRoom##H#Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::add(int,int,class Room *)" (?add#Layout##QAEXHHPAVRoom###Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::clear(int,int,bool)" (?clear#Layout##QAEXHH_N#Z) referenced in function __catch$?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ$0
1>C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.dll : fatal error LNK1120: 4 unresolved externals
If I'm not mistaken, this means that the compiler finds the header files, but not the source files. What am I missing?
Here is a step-by-step description on how to add an EXE as an unit-test target.
The key point is to "export" the functions/classes you want to test... You can download the complete sample here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip (I did not change any project settings, so all changes you can see in the source-code; of course, some parts can be made in the project settings).
Create a Win32 Application (Console or MFC or Windows, does not matter); I created a console project called CPP_UnitTestApp:
Add a function you want to test (you can also add classes). For example:
int Plus1(int i)
{
return i+1;
}
Add a header file for the functions you want to test: CPP_UnitTestApp.h
Put the declaration of the methods into the header file, and also export these functions!
#pragma once
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CPP_UNITTESTAPP_EXPORT __declspec(dllexport)
#else
#define MY_CPP_UNITTESTAPP_EXPORT
#endif
MY_CPP_UNITTESTAPP_EXPORT int Plus1(int i);
Include this header file in the main-cpp (here CPP_UnitTestApp.cpp) and define the EXPORT_TEST_FUNCTIONS before including the header:
#define EXPORT_TEST_FUNCTIONS
#include "CPP_UnitTestApp.h"
Now add a new project (Native unit test project: UnitTest1)
Include the header and the lib to the "unittest1.cpp" file (adopt the paths as you want):
#include "..\CPP_UnitTestApp.h"
#pragma comment(lib, "../Debug/CPP_UnitTestApp.lib")
Go to the project settings of the test project add add a reference to the "UnitTest1" project (Project|Properties|Common Properties|Add New Reference...: Select under "Projects" the "CPP_UnitTestApp"-Project)
Create the unit test function:
TEST_METHOD(TestMethod1)
{
int res = Plus1(12);
Assert::AreEqual(13, res);
}
Run your unit test ;)
As you can see, the main point was to export the function declaration! This is done via __declspec(dllexport) even if it is an EXE.
As I said, the demo project can be downloaded here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip

Linking with glog library

I'm trying to use the glog logging library (LINK).
In VS2012 (I'm on Windows 8 Professional 64-bit (Japanese)), I create an empty solution with a single main.cpp file like the one in the documentation (LINK).
Also I import the glog project inside the solution (either the dll one or the static library one) and set the project dependency.
To avoid some errors I have to comment out line 97 from port.h:
/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */
#define hash hash_compare
While glog compiles, the main application gives me unresolved external symbol erros (with both dll and static version).
1>main.obj : error LNK2019: 未解決の外部シンボル "void __cdecl google::InitGoogleLogging(char const *)" (?InitGoogleLogging#google##YAXPBD#Z) が関数 _main で参照されました。
1>main.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall google::LogMessage::LogMessage(char const *,int)" (??0LogMessage#google##QAE#PBDH#Z) が関数 _main で参照されました。
1>main.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall google::LogMessage::~LogMessage(void)" (??1LogMessage#google##QAE#XZ) が関数 _main で参照されました。
I'm compiling as Win32.
If I check the debug folder it actually contains the dll+lib or static lib file.
I also tried linking to the library manually without using the visual studio dependency system, but it's the same.
I've built glog for MSVS2012 from trunk (little patch mentioned in header already presented here, as i know), so it works for me.
Looks like your dependency description of glog library is missing.
Can you add windows-specific
#pragma comment(lib, "path_to_glog_from_project_dir.lib")
to one of your project files, for example, directly into main.cpp and test it.

'Unresolved external symbol' errors

I am using an example program that is supposed to allow control of MIDI devices using a protocol called OSC.
What I have done is downloaded the SDK from here: http://mac.softpedia.com/get/Development/Libraries/oscpack.shtml
The 'examples' folder contains a file called 'SimpleSend.cpp'. The code for this is as follows:
#include "osc/OscOutboundPacketStream.h"
#include "ip/UdpSocket.h"
#define ADDRESS "127.0.0.1"
#define PORT 7000
#define OUTPUT_BUFFER_SIZE 1024
int main(int argc, char* argv[])
{
UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );
char buffer[OUTPUT_BUFFER_SIZE];
osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );
p << osc::BeginBundleImmediate
<< osc::BeginMessage( "/test1" )
<< true << 23 << (float)3.1415 << "hello" << osc::EndMessage
<< osc::BeginMessage( "/test2" )
<< true << 24 << (float)10.8 << "world" << osc::EndMessage
<< osc::EndBundle;
transmitSocket.Send( p.Data(), p.Size() );
}
I have opened Visual C++ and created a new (CLR console application) project, called 'osctemp'. I copy the code from the 'SimpleSend.cpp' file and paste this into the main cpp file that is created for my project, keeping the following lines of code from the default project file:
#include "stdafx.h"
using namespace System;
I then navigate to the stdafx.h header file and notice that it contains at the bottom the line:
// TODO: reference additional headers your program requires here
...So I obediently move the includes and defines from my main cpp file to here.
I also notice that I need to add the includes to my project so in Windows Explorer I copy the folders 'osc' and 'ip' into my project folder.
Upon running, I receive the following errors:
1>------ Build started: Project: osctemp, Configuration: Debug Win32 ------
1> stdafx.cpp
1> AssemblyInfo.cpp
1> osctemp.cpp
1> Generating Code...
1> .NETFramework,Version=v4.0.AssemblyAttributes.cpp
1>osctemp.obj : error LNK2028: unresolved token (0A00000A) "public: char const * __thiscall osc::OutboundPacketStream::Data(void)const " (?Data#OutboundPacketStream#osc##$$FQBEPBDXZ) referenced in function "int __cdecl main(int,char * * const)" (?main##$$HYAHHQAPAD#Z)
1>osctemp.obj : error LNK2028: unresolved token (0A00000B) "public: unsigned int __thiscall osc::OutboundPacketStream::Size(void)const " (?Size#OutboundPacketStream#osc##$$FQBEIXZ) referenced in function "int __cdecl main(int,char * * const)" (?main##$$HYAHHQAPAD#Z)
1>osctemp.obj : error LNK2028: unresolved token (0A00000C) "public: void __thiscall UdpSocket::Send(char const *,int)" (?Send#UdpSocket##$$FQAEXPBDH#Z) referenced in function "int __cdecl main(int,char * * const)" (?main##$$HYAHHQAPAD#Z)
...(And many more like this)...
1>D:\Temp\OSCTEMP\osctemp\Debug\osctemp.exe : fatal error LNK1120: 40 unresolved externals
What have I missed?
From your problem description I can't find anything about how you link towards the SDK libraries. Have you done so?
To link with the SDK libraries you need one or more .lib files. Even if the SDK is distributed as DLL you need a lib file for the build-time linkage. You should read through the SDK documentation and look for guidelines about link dependencies.
If you can't seem to find any lib-files in the SDK distribution it could very well be that you need to first build the SDK to produce a library and then link towards it. Alternatively, if the SDK comes with a ready VS project you can add it to your solution and set your own project to depend on it (i.e. VS does the work of finding the output lib and linking with it).
Again, if the SDK is of any descent standard, there should be docs about building the SDK yourself if that's necessary.
Good luck.
You're either not pulling in the correct library, or your prototype is not defining the library function correctly according to what's actually in it.

Help on jrtplib and jthread

I have some link error problems when trying to compile using jrtplib and jthread on my simple project. The errors are:
Error 4 fatal error LNK1120: 3 unresolved externals C:\Users\Chicko\Desktop\tryout\Debug\tryout.exe
Error 1 error LNK2019: unresolved external symbol "public: virtual __thiscall RTPSession::~RTPSession(void)" (??1RTPSession##UAE#XZ) referenced in function _wmain tryout.obj
Error 2 error LNK2019: unresolved external symbol "public: __thiscall RTPSessionParams::RTPSessionParams(void)" (??0RTPSessionParams##QAE#XZ) referenced in function _wmain tryout.obj
Error 3 error LNK2019: unresolved external symbol "public: __thiscall RTPSession::RTPSession(class RTPRandom *,class RTPMemoryManager *)" (??0RTPSession##QAE#PAVRTPRandom##PAVRTPMemoryManager###Z) referenced in function _wmain tryout.obj
and here is my main program:
// tryout.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <rtpsession.h> //Confused to put "" or <>
#include <rtpsessionparams.h>
#include <rtpudpv4transmitter.h>
int _tmain(int argc, _TCHAR* argv[])
{
RTPSession session;
RTPSessionParams sessionparams;
RTPUDPv4TransmissionParams transparams;
sessionparams.SetOwnTimestampUnit(1.0/8000.0);
transparams.SetPortbase(8000);
return 0;
}
For your information, I do not import any header file from those libraries into my project. I use additional include libraries in the project setting and put `"..\jlib\jthread-1.2.1\src";"..\jlib\jrtplib3.8.2\src" (this is the folder where all the headers are stored). How do I fix this? Where should i put jrtplib.lib and jthread.lib? Please help...
Have you added jrtplib.lib and jthread.lib under your project linker options?
You can do this on the project property page under
"Configuration properties->Linker->Input->Additional Dependencies" and make sure that the directory that contains the lib files has been added to your library path: Either on the project properties
"Linker->General->Additional Library Directories"
or under the global VS settings (Doesn't apply to VC2010)
"Tools->Options" "Projects and Solutions->VC++ Directories->Library Files"
Under VC2010 you'll have to edit the property sheet of the project.
I see that it's a bit late to answer and I'm not so expert on Windows (I'm more a Linux user), but some day ago I've tried JRTPLIB on Windows and I had the same problem when I compiled the example in release mode and the lib in debug mode (I see that you use the debug mode). Hope it can help.