protocolbuffers / protobuf

Protocol Buffers - Google's data interchange format
http://protobuf.dev
Other
65.6k stars 15.48k forks source link

undefined reference to `utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits<char> >) #19007

Open ivanzz1001 opened 4 days ago

ivanzz1001 commented 4 days ago

I build brpc(https://github.com/apache/brpc) and meet the following when It link protobuf:

/root/cpp_proj/brpc-compile/protobuf/src/google/protobuf/generated_message_tctable_lite.cc:1419: undefined reference to `utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits<char> >)'
/usr/bin/ld: /root/cpp_proj/brpc-compile/protobuf/output-inst/lib/libprotobuf.a(generated_message_tctable_lite.cc.o): in function `google::protobuf::internal::TcParser::FastUS2(google::protobuf::MessageLite*, char const*, google::protobuf::internal::ParseContext*, google::protobuf::internal::TcFieldData, google::protobuf::internal::TcParseTableBase const*, unsigned long)':
/root/cpp_proj/brpc-compile/protobuf/src/google/protobuf/generated_message_tctable_lite.cc:1419: undefined reference to `utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits<char> >)'

My protobuf version is 'tags/v4.25.0' and I use the following command to build my protobuf:

# mkdir build output-inst && cd build && pwd
# cmake -G "Unix Makefiles"  -DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=/root/cpp_proj/brpc-compile/protobuf/output-inst ..

# make -j2
# make install

When I built out the 'libprotobuf.a', I checked my protobuf has already linked 'utf8_validity':

# pkg-config --libs-only-l protobuf
-lprotobuf -labsl_log_internal_check_op -labsl_leak_check -labsl_die_if_null -labsl_log_internal_conditions -labsl_log_internal_message -labsl_examine_stack -labsl_log_internal_format -labsl_log_internal_proto -labsl_log_internal_nullguard -labsl_log_internal_log_sink_set -labsl_log_sink -labsl_log_entry -labsl_flags_internal -labsl_flags_marshalling -labsl_flags_reflection -labsl_flags_private_handle_accessor -labsl_flags_commandlineflag -labsl_flags_commandlineflag_internal -labsl_flags_config -labsl_flags_program_name -labsl_log_initialize -labsl_log_globals -labsl_vlog_config_internal -labsl_log_internal_fnmatch -labsl_log_internal_globals -labsl_raw_hash_set -labsl_hash -labsl_city -labsl_low_level_hash -labsl_hashtablez_sampler -labsl_statusor -labsl_status -labsl_cord -labsl_cordz_info -labsl_cord_internal -labsl_cordz_functions -labsl_exponential_biased -labsl_cordz_handle -labsl_crc_cord_state -labsl_crc32c -labsl_crc_internal -labsl_crc_cpu_detect -labsl_bad_optional_access -labsl_strerror -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_kernel_timeout_internal -labsl_stacktrace -labsl_symbolize -labsl_debugging_internal -labsl_demangle_internal -labsl_malloc_internal -labsl_time -labsl_civil_time -labsl_time_zone -labsl_bad_variant_access -lutf8_validity -lutf8_range -labsl_strings -labsl_strings_internal -labsl_string_view -labsl_base -lrt -labsl_spinlock_wait -labsl_int128 -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity

But why It stills report: undefined reference to `utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits >)'

Can anyone help me ?

ivanzz1001 commented 4 days ago

utf8_range::IsStructurallyValid(std::basic_string_view<char, std::char_traits >) is realized in libutf8_validity.a:

# strings libutf8_validity.a | grep IsStructurallyValid
B_ZN10utf8_range19IsStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE
IsStructurallyValid
_ZN10utf8_range19IsStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE
_ZN10utf8_range19IsStructurallyValidESt17basic_string_viewIcSt11char_traitsIcEE
sbenzaquen commented 22 hours ago

I think this might be an issue with how Abseil is configured in your system. Both protobuf and utf8_range use absl::string_view in their APIs. Abseil itself has a configuration where you can make absl::string_view be an alias to std::string_view.

From the linker error I think the protobuf library is built with the aliasing on (which is why it is looking for IsStructurallyValid(std::string_view)), but the utf8_range library has it off.

You can see the Abseil option here https://abseil.io/docs/cpp/guides/options https://github.com/abseil/abseil-cpp/blob/fa588813c4b2d931737bbe7c4b4f7fa6ed7509db/absl/base/options.h#L127

By default Abseil will autodetect the presence of std::string_view and alias if it is there. However, this means that if you try to mix libraries built with different configs (eg one at C++14 and one at C++17) you might get conflicting answers. For those cases, you should manually specify -DABSL_OPTION_USE_STD_STRING_VIEW=0 on all builds to make sure they all agree.