Comment #14 on issue 449 by
cvet...@gmail.com: Link error while using
I have been bumping HARD into this one too.
The default one within clang is libstdc++, so providing -lc++ results in
that being linked to as well. Only -stdlib=libc++ option should be used if
you don't want a library linked to both stdc++ and c++ libs.
For me the problem seems to be that somehow LDFLAGS is somehow ignored when
I do make (I provide LDFLAGS=-stdlib=libc++ on ./configure). This is the
command called:
/bin/sh ../libtool --tag=CXX --mode=link /usr/bin/clang++ -D_THREAD_SAFE
-Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
-stdlib=libc++ -version-info 7:0:0 -export-dynamic -no-undefined -o
libprotobuf.la -rpath
/Users/cvetan/workspace/tundra/deps/osx-64/protobuf/lib common.lo once.lo
extension_set.lo generated_message_util.lo message_lite.lo
repeated_field.lo wire_format_lite.lo coded_stream.lo zero_copy_stream.lo
zero_copy_stream_impl_lite.lo strutil.lo substitute.lo
structurally_valid.lo descriptor.lo descriptor.pb.lo descriptor_database.lo
dynamic_message.lo extension_set_heavy.lo generated_message_reflection.lo
message.lo reflection_ops.lo service.lo text_format.lo unknown_field_set.lo
wire_format.lo gzip_stream.lo printer.lo tokenizer.lo
zero_copy_stream_impl.lo importer.lo parser.lo -lz -stdlib=libc++
and this is actually executed (notice that there is no mentioning of libc++
here) :
libtool: link: /usr/bin/clang++ -dynamiclib
-o .libs/libprotobuf.7.dylib .libs/common.o .libs/once.o .libs/extension_set.o .libs/generated_message_util.o .libs/message_lite.o .libs/repeated_field.o .libs/wire_format_lite.o .libs/coded_stream.o .libs/zero_copy_stream.o .libs/zero_copy_stream_impl_lite.o .libs/strutil.o .libs/substitute.o .libs/structurally_valid.o .libs/descriptor.o .libs/descriptor.pb.o .libs/descriptor_database.o .libs/dynamic_message.o .libs/extension_set_heavy.o .libs/generated_message_reflection.o .libs/message.o .libs/reflection_ops.o .libs/service.o .libs/text_format.o .libs/unknown_field_set.o .libs/wire_format.o .libs/gzip_stream.o .libs/printer.o .libs/tokenizer.o .libs/zero_copy_stream_impl.o .libs/importer.o .libs/parser.o
-lz -install_name
/Users/cvetan/workspace/tundra/deps/osx-64/protobuf/lib/libprotobuf.7.dylib
-compatibility_version 8 -current_version 8.0 -Wl,-single_module
which will result into the following:
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::find_first_of(char const*, unsigned long,
unsigned long) const", referenced from:
void
google::protobuf::SplitStringToIteratorUsing<std::__1::back_insert_iterator<std::__1::vector<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >,
std::__1::allocator<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> > const&, char const*,
std::__1::back_insert_iterator<std::__1::vector<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >,
std::__1::allocator<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > > > >&) in
strutil.o
"std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::find_first_not_of(char const*, unsigned long,
unsigned long) const", referenced from:
void
google::protobuf::SplitStringToIteratorUsing<std::__1::back_insert_iterator<std::__1::vector<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >,
std::__1::allocator<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> > const&, char const*,
std::__1::back_insert_iterator<std::__1::vector<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >,
std::__1::allocator<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > > > >&) in
strutil.o
"std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::find(char const*, unsigned long, unsigned
long) const", referenced from:
google::protobuf::StringReplace(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > const&, std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >*) in strutil.o
google::protobuf::compiler::ContainsParentReference(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&) in
importer.o
"std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::find(char, unsigned long) const", referenced
from:
google::protobuf::DescriptorBuilder::LookupSymbolNoPlaceholder(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > const&,
google::protobuf::DescriptorBuilder::ResolveMode) in descriptor.o
"std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::rfind(char, unsigned long) const", referenced
from:
google::protobuf::DescriptorBuilder::AddPackage(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
google::protobuf::Message const&, google::protobuf::FileDescriptor const*)
in descriptor.o
google::protobuf::DescriptorBuilder::AddSymbol(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&, void
const*, std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > const&, google::protobuf::Message const&,
google::protobuf::(anonymous namespace)::Symbol) in descriptor.o
google::protobuf::DescriptorBuilder::LookupSymbolNoPlaceholder(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > const&,
google::protobuf::DescriptorBuilder::ResolveMode) in descriptor.o
google::protobuf::DescriptorBuilder::NewPlaceholder(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
google::protobuf::DescriptorBuilder::PlaceholderType) in descriptor.o
So one workaround is (which is the one I used) to "lie" that the CXX
compiler is actually "/usr/bin/clang++ -stdlib=libc++" instead of
plain "/usr/bin/clang++" to make sure your -stdlib=libc++ is not ignored.
And there you go
libprotobuf.7.dylib:
@executable_path/../lib/libprotobuf.7.dylib (compatibility version 8.0.0,
current version 8.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version
65.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
169.3.0)