Unresolved External Symbols when using gRPC in C++

Viewed 6411

Win10, Visual Studio 15 2017

That's what I've done so far:

  • cloned grpc and the submodules from github
  • cmake --build on grpc
  • generated pb.cc and pb.h files from my proto-files
  • added grpc and protobuf to VC++ Directories, Include Directories
  • added zlib, grpc and protobuf to VC++ Directories, Library Directories
  • added zlib.lib, gpr.lib, grpc.lib, grpc++.lib and libprotobuf.lib to Linker, Input, Additional Dependencies
  • added Preprocessor Definitions: _WIN32_WINNT=0x600; NDEBUG
  • changed Runtime Library to /MD

After that my empty project including the pb-files compiled without an error.

Then I wrote some code to use and test grpc but when I try to compile this time, I'm getting several errors like

LNK2019 unresolved external symbol _address_sorting_init referenced in function "void __cdecl grpc_resolver_dns_ares_init(void)" (?grpc_resolver_dns_ares_init@@YAXXZ) grpc.lib(dns_resolver_ares.obj)  
LNK2001 unresolved external symbol __imp__htons@4 grpc.lib(socket_utils_windows.obj)    
LNK2019 unresolved external symbol _ares_gethostbyname referenced in function "struct grpc_ares_request * __cdecl grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(char const *,char const *,char const *,struct grpc_pollset_set *,struct grpc_closure *,struct grpc_lb_addresses * *,bool,char * *,struct grpc_combiner *)" (?grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked@@YAPAUgrpc_ares_request@@PBD00PAUgrpc_pollset_set@@PAUgrpc_closure@@PAPAUgrpc_lb_addresses@@_NPAPADPAUgrpc_combiner@@@Z)   grpc.lib(grpc_ares_wrapper.obj)
5 Answers

The first error:

LNK2019 unresolved external symbol _address_sorting_init referenced in function "void __cdecl grpc_resolver_dns_ares_init(void)" (?grpc_resolver_dns_ares_init@@YAXXZ) grpc.lib(dns_resolver_ares.obj)  

can be resolved by adding the address_sorting.lib. This lib is in the grpc build directory, same as grpc++.lib, grpc.lib and gpr.lib.

The second error:

LNK2001 unresolved external symbol __imp__htons@4 grpc.lib(socket_utils_windows.obj)

can be resolved by adding ws2_32.lib as per Nicolas suggested.

The third error:

LNK2019 unresolved external symbol _ares_gethostbyname referenced in function "struct grpc_ares_request * __cdecl grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(char const *,char const *,char const *,struct grpc_pollset_set *,struct grpc_closure *,struct grpc_lb_addresses * *,bool,char * *,struct grpc_combiner *)" (?grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked@@YAPAUgrpc_ares_request@@PBD00PAUgrpc_pollset_set@@PAUgrpc_closure@@PAPAUgrpc_lb_addresses@@_NPAPADPAUgrpc_combiner@@@Z)   grpc.lib(grpc_ares_wrapper.obj)

can be resolved by adding the cares.lib. You should be able to find this lib file under the third_party\cares\cares\lib directory inside the grpc build directory, no need to get it from elsewhere.

As a summary, suppose your grpc build directory is c:\grpc\.build, here are the libraries required for building a Release version application:

c:\grpc\.build\grpc++.lib
c:\grpc\.build\gpr.lib
c:\grpc\.build\grpc.lib
c:\grpc\.build\address_sorting.lib
c:\grpc\.build\third_party\protobuf\libprotobuf.lib
c:\grpc\.build\third_party\zlib.lib
c:\grpc\.build\third_party\cares\cares\lib\cares.lib
ws2_32.lib

If you want to build a Debug version of your application, please build a Debug version of grpc first, and then reference the libraries from the grpc debug version. To build a debug version with Ninja:

> md .debug
> cd .debug
> call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug
> cmake --build .

Please change above directory of vcvarsall.bat according to your Visual Studio installation.

Please also note the Debug version of protobuf library file's name is libprotobufd.lib, not libprotobuf.lib.

In my case I had to add all these libs to resolve all unresolved external symbols issues

libprotobufd.lib
gpr.lib
grpc.lib
grpc++.lib
grpc++_reflection.lib
address_sorting.lib
ws2_32.lib
cares.lib
zlibstaticd.lib
upb.lib
ssl.lib
crypto.lib
absl_bad_any_cast_impl.lib
absl_bad_optional_access.lib
absl_bad_variant_access.lib
absl_base.lib
absl_city.lib
absl_civil_time.lib
absl_cord.lib
absl_debugging_internal.lib
absl_demangle_internal.lib
absl_dynamic_annotations.lib
absl_examine_stack.lib
absl_exponential_biased.lib
absl_failure_signal_handler.lib
absl_flags.lib
absl_flags_config.lib
absl_flags_internal.lib
absl_flags_marshalling.lib
absl_flags_parse.lib
absl_flags_program_name.lib
absl_flags_registry.lib
absl_flags_usage.lib
absl_flags_usage_internal.lib
absl_graphcycles_internal.lib
absl_hash.lib
absl_hashtablez_sampler.lib
absl_int128.lib
absl_leak_check.lib
absl_leak_check_disable.lib
absl_log_severity.lib
absl_malloc_internal.lib
absl_periodic_sampler.lib
absl_random_distributions.lib
absl_random_internal_distribution_test_util.lib
absl_random_internal_pool_urbg.lib
absl_random_internal_randen.lib
absl_random_internal_randen_hwaes.lib
absl_random_internal_randen_hwaes_impl.lib
absl_random_internal_randen_slow.lib
absl_random_internal_seed_material.lib
absl_random_seed_gen_exception.lib
absl_random_seed_sequences.lib
absl_raw_hash_set.lib
absl_raw_logging_internal.lib
absl_scoped_set_env.lib
absl_spinlock_wait.lib
absl_stacktrace.lib
absl_status.lib
absl_strings.lib
absl_strings_internal.lib
absl_str_format_internal.lib
absl_symbolize.lib
absl_synchronization.lib
absl_throw_delegate.lib
absl_time.lib
absl_time_zone.lib

With these libraries linked it works for me (in VS2015 and Win10):

grpc++, grpc, gpr, libprotobuf, zlibstatic, ssl, crypto

The last 2 are in the third_party/boringssl directory.

I hit this using conan to build grpc. I found it much easier change the grpc conanfile to use CMake install to collect all the necessary libraries. The GRPC authors maintain the install target for this purpose.

Conan tools' collect_libs (docs) also means you don't have to explicitly list them all yourself; they get generated into the props and then visual studio uses them from there.

Related