Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined symbols _gpr_set_log_function #1

Closed
kawanet opened this issue Sep 3, 2021 · 4 comments
Closed

Undefined symbols _gpr_set_log_function #1

kawanet opened this issue Sep 3, 2021 · 4 comments

Comments

@kawanet
Copy link
Contributor

kawanet commented Sep 3, 2021

commit 861ec40 fails to build on the following environments:

  • M1 Mac: macOS 11.4 ARM
  • Intel Mac: macOS 11.4 Intel
  • Amazon Linux Intel

Linker fails with Undefined symbols or undefined reference error messages around _gpr_set_log_function.

gRPC is installed via brew or from source.
tkrzw is installed locally at $HOME/local/tkrzw.

On M1 Mac:

$ make

(snip)

g++ -g -O2 -std=c++17 -Wall -fPIC -fsigned-char -O2 -O3 -mcpu=native -dynamiclib -o libtkrzw_rpc.1.3.0.dylib \
	  -install_name /Users/xxxx/local/tkrzw/lib/libtkrzw_rpc.1.dylib \
	  -current_version 1.3.0 -compatibility_version 1 \
	  tkrzw_rpc_common.o tkrzw_dbm_remote.o tkrzw_rpc.pb.o tkrzw_rpc.grpc.pb.o -L/Users/xxxx/local/tkrzw/lib -L. -L/Users/xxxx/local/tkrzw/lib -L/Users/xxxx/lib -L/usr/local/lib -L/Users/xxxx/local/tkrzw/lib -ltkrzw -llzma -lz -lstdc++ -lpthread -lm -lc 
ld: warning: directory not found for option '-L/Users/xxxx/lib'
ar: creating archive libtkrzw_rpc.a
a - tkrzw_rpc_common.o
a - tkrzw_dbm_remote.o
a - tkrzw_rpc.pb.o
a - tkrzw_rpc.grpc.pb.o
Undefined symbols for architecture arm64:
  "grpc::ClientContext::ClientContext()", referenced from:
      tkrzw::RemoteDBMImpl::Echo(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in tkrzw_dbm_remote.o
      tkrzw::RemoteDBMImpl::Inspect(std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >*) in tkrzw_dbm_remote.o
      tkrzw::RemoteDBMImpl::Get(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in tkrzw_dbm_remote.o
(snip)
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "_gpr_set_log_function", referenced from:
      tkrzw::SetGlobalLogger(tkrzw::Logger*) in tkrzw_rpc_common.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libtkrzw_rpc.1.3.0.dylib] Error 1
make: *** Waiting for unfinished jobs....

On Intel Mac:

$ make

(snip)

g++ -g -O2 -std=c++17 -Wall -fPIC -fsigned-char -O2 -O3 -march=native -dynamiclib -o libtkrzw_rpc.1.3.0.dylib \
	  -install_name /Users/xxxx/local/tkrzw/lib/libtkrzw_rpc.1.dylib \
	  -current_version 1.3.0 -compatibility_version 1 \
	  tkrzw_rpc_common.o tkrzw_dbm_remote.o tkrzw_rpc.pb.o tkrzw_rpc.grpc.pb.o -L/Users/xxxx/local/tkrzw/lib -L. -L/Users/xxxx/local/tkrzw/lib -L/Users/xxxx/lib -L/usr/local/lib -L/Users/xxxx/local/tkrzw/lib -lgrpc++_reflection -lgrpc++ -lgrpc -lprotobuf -ltkrzw -llzma -llz4 -lzstd -lz -lstdc++ -lpthread -lm -lc 
ar: creating archive libtkrzw_rpc.a
a - tkrzw_rpc_common.o
a - tkrzw_dbm_remote.o
a - tkrzw_rpc.pb.o
a - tkrzw_rpc.grpc.pb.o
ld: warning: directory not found for option '-L/Users/xxxx/lib'
Undefined symbols for architecture x86_64:
  "_gpr_set_log_function", referenced from:
      tkrzw::SetGlobalLogger(tkrzw::Logger*) in tkrzw_rpc_common.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libtkrzw_rpc.1.3.0.dylib] Error 1
make: *** Waiting for unfinished jobs....

On Intel Amazon Linux

$ make

(snip)

g++ -g -O2 -std=c++17 -Wall -fPIC -fsigned-char -O2 -O3 -march=native -o tkrzw_dbm_remote_perf tkrzw_dbm_remote_perf.o -L/home/ec2-user/local/tkrzw/lib -L. -L/home/ec2-user/local/tkrzw/lib -L/home/ec2-user/lib -L/usr/local/lib -L/home/ec2-user/local/tkrzw/lib -Wl,-rpath-link,.:/usr/local/lib:/home/ec2-user/lib:/usr/local/lib::/home/ec2-user/local/tkrzw/lib -Wl,--as-needed -L. -L/home/ec2-user/local/tkrzw/lib -ltkrzw_rpc -ltkrzw -lstdc++ -lrt -lpthread -lm -lc 
./libtkrzw_rpc.so: undefined reference to `typeinfo for google::protobuf::io::ZeroCopyOutputStream'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::internal::ComputeUnknownFieldsSize(google::protobuf::internal::InternalMetadata const&, unsigned long, google::protobuf::internal::CachedSize*)'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::Message::CheckTypeAndMergeFrom(google::protobuf::MessageLite const&)'
./libtkrzw_rpc.so: undefined reference to `grpc::ClientContext::~ClientContext()'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::internal::VerifyUTF8(google::protobuf::StringPiece, char const*)'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]'
./libtkrzw_rpc.so: undefined reference to `gpr_set_log_function'
./libtkrzw_rpc.so: undefined reference to `grpc::Channel::GetState(bool)'
./libtkrzw_rpc.so: undefined reference to `google::protobuf::internal::ReadSizeFallback(char const*, unsigned int)'

Steps before calling make on macOS:

brew install grpc

cd tkrzw
./configure --enable-opt-native --enable-most-features --prefix=$HOME/local/tkrzw
make all install

cd ../tkrzw-rpc
BREW=$(brew config | grep HOMEBREW_PREFIX | cut -f 2 -d ' ') # => /opt/homebrew or /usr/local

PKG_CONFIG_PATH=$HOME/local/tkrzw/lib/pkgconfig \
LDFLAGS="-L$BREW/lib -L$HOME/local/tkrzw/lib" \
CPPFLAGS="-I$BREW/include -I$HOME/local/tkrzw/include" \
./configure  --prefix=$HOME/local/tkrzw 

(snip)

checking for main in -ltkrzw... yes
checking for main in -lprotobuf... yes
checking for main in -lgrpc... yes
checking for main in -lgrpc++... yes
checking for main in -lgrpc++_reflection... yes
checking for main in -ltkrzw_rpc... no

(snip)

make
@estraier
Copy link
Owner

estraier commented Sep 3, 2021

Hi Yusuke,
Thanks for reporting this issue.
I found the error on my M1 macbook.
As a workaround, commenting out the following line in tkrzw_rpc_common.h solves this.

void SetGlobalLogger(tkrzw::Logger* logger) {
g_logger = logger;
//gpr_set_log_function(PrintGlobalLog);
}

The reason why we call gpr_set_log_function is that gRPC's internal logger sometimes writes error logs to stderr, which is annoying for me. However, it is not a critical issue. so, commenting it out is practical.

One strange thing is that gpr_set_log_function is defined in grpc/impl/codegen/log.h .
So, somehow, the library doesn't embed the symbol of gpr_set_log_function.
I'm investigating more.

@estraier
Copy link
Owner

estraier commented Sep 3, 2021

I found it. Adding -lgpr to LDFLAGS solves this issue. I don't know why it is not necessary on Linux though.

@estraier
Copy link
Owner

estraier commented Sep 3, 2021

I submitted the fix so please check it.

@kawanet
Copy link
Contributor Author

kawanet commented Sep 3, 2021

hooray!

$ make -j4 && echo 🎉
(snip)
#================================================================
# Ready to install.
#================================================================
🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants