udata.cpp: undefined reference to `icudt71_dat' - c++

I am getting an odd ICU related linking error in the now project when building on Ubuntu 22.04.
/usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x23
/home/bkey1/vcpkg/installed/x64-linux/debug/lib/libicuuc.a(udata.ao): in function `openCommonData(char const*, int, UErrorCode*)':
udata.cpp:(.text+0x23f7): undefined reference to `icudt71_dat'
/usr/bin/ld: udata.cpp:(.text+0x2458): undefined reference to `icudt71_dat'
The link command is as follows.
usr/bin/cmake -E cmake_link_script CMakeFiles/now.dir/link.txt --verbose=1
/usr/bin/c++ -std=c++2a -Wall -Wextra -Wfloat-equal -Wno-long-long -Wpedantic -funsigned-char -D_GNU_SOURCE=1 -rdynamic CMakeFiles/now.dir/GetStardate.cpp.o CMakeFiles/now.dir/GetTime.cpp.o CMakeFiles/now.dir/GetTimePlatformPOSIX.cpp.o CMakeFiles/now.dir/GetTimePlatformWin32.cpp.o CMakeFiles/now.dir/ISO8601_time.cpp.o CMakeFiles/now.dir/InitLocale.cpp.o CMakeFiles/now.dir/executable_path.cpp.o CMakeFiles/now.dir/now.cpp.o CMakeFiles/now.dir/nowStrings.cpp.o -o now /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_chrono.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_filesystem.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_locale.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_log.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_program_options.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_regex.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_system.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_thread.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_date_time.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_log_setup.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libboost_atomic.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libicudata.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libicui18n.a /home/bkey1/vcpkg/installed/x64-linux/debug/lib/libicuuc.a

First I would like to stress, that there is very little information provided, so the answers such as my own will most likely need to guess what is happening. On the other hand I understand your situation: you cannot include info, that you don't know is relevant to the topic.
Answer:
I would like to draw your attention to the fact, that the symbol icudt71_dat does not appear anywhere in the code directly, but is generated using a macro. (Check .../source/common/unicode/utypes.h) So if the linker complains about not having found such a symbol it most probably means you are linking against a different version of the library than you have a header for. Now I don't know how specifically this could have happened, I would have to see your system, include path, link path etc. However I strongly suggest to revisit both include and link paths. You could perhaps recompile the library, verify, there is no other version recompile and start again. If the header corresponds to the source, it should work.

Aparently you missing icu-devtools package. Install that with command
sudo apt get install icu-devtools

Related

g++ undefined reference error when linking to third party shared libraries

I'm trying to link a c++ program that uses several shared libraries from 3rd parties. Mainly, these libraries come from a github project called MBSim and I downloaded the latest daily build with all its binaries, libraries and headers, which I installed on /usr/local/mbsim-env.
The most important libraries called are libmbsim, libopenmbvcppinterface, libfmatvec and libboost_filesystem (the last one comes with the MBSim distro).
I set up a simple code to test it and it compiles like a charm using
g++ main.cpp -m64 -g3 -std=c++11 -Wall
-Wfatal-errors -Werror -Wno-unknown-pragmas -fopenmp
`pkg-config --cflags mbsim` -I. -c -o main.o
The pkg-config part calls, as you can wonder, the include directories and flags:
-DHAVE_ANSICSIGNAL -DHAVE_OPENMBVCPPINTERFACE -DHAVE_BOOST_FILE_LOCK
-I/usr/local/mbsim-env/include
-I/usr/include/x86_64-linux-gnu
-I/usr/include/x86_64-linux-gnu/c++/5
-I/usr/local/include
My problems appear when I try to link the objects with the pre-compiled libraries with:
g++ system.o main.o -o teste -L/usr/local/mbsim-env/lib
-lmbsim -lopenmbvcppinterface -lboost_system
-lfmatvec -lm
-Wl,-rpath,/usr/local/mbsim-env/lib
Edit: On the above command, I've tried to use pkg-config --libs as well. The results remain the same.
First of all, the linker issues a warning that I'm linking against an older boost library:
/usr/bin/ld: warning: libboost_system.so.1.53.0,
needed by /usr/local/mbsim-env/lib/libmbsim.so,
may conflict with libboost_system.so.1.61.0
I'm aware of that, but I intentionally want to link against the old one because that's the one that was used to compile the MBSim libraries.
After that, I got several undefined reference warnings for almost every method that I call from MBSim:
system.cpp:59: undefined reference to
MBSim::RigidBody::RigidBody(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
It seems to me that this error means that the target libraries don't have the RigidBody method implemented. Well, I know they do.
My first guess was that maybe the linker was looking at the wrong library path, so I set LD_LIBRARY_PATH=/usr/local/mbsim-env/lib and added the -rpath to the same folder. That didn't help at all.
Some googling showed me that the problem could be compiling in 64bits and linking it against 32bits libs. I believe that's not the case: I've done everything in Ubuntu 16.04 64bits and the MBSim libraries are also 64bits.
Could somebody point me out of this dead end?
Could it be that your 3rd party shared libraries are compiled using an older version of GCC? There was a new ABI introduced in GCC 5. It's probably enabled by default on your platform. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html.
You could try switching to the older ABI, but that might require your other libraries to have been compiled with the old ABI also. You might also be able to switch ABIs for the 3rd party libraries explicitly.
undefined reference to MBSim::RigidBody::RigidBody(std::__cxx11::basic_string<std::char_traits<char>, std::allocator<char> > const&)
This is a reference to MBSim::RigidBody::RigidBody(const string&), compiled with g++ -std=c++11 and g++ version 5 or later.
As any1 probably correctly guessed, the binary for libmbsim.so that you downloaded was built with g++ 4.x, and defines the same function with this signature:
MBSim::RigidBody::RigidBody(std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)
Note lack of __cxx11 namespace. You can easily confirm or disprove this:
nm -C libmbsim.so | grep 'MBSim::RigidBody::RigidBody'
If this mismatch is indeed the cause, simply rebuild this project from source with your compiler. That's what open source is for.

Getting undefined reference error but nm shows symbol present

I am building a large application using libkml. I am using the cmake port of libkml from here: https://github.com/rashadkm/libkml
I am getting a stranged undefined reference to symbol error even thought the symbol appears to be referenced and defined.
This is the make command:
/usr/bin/c++ -fPIC -Werror=return-type -Werror=return-type -Wall
-Werror=parentheses -Werror=uninitialized -Werror=missing-braces
-fPIC -O0 -Wall -fPIC -fvisibility=hidden -fno-strict-aliasing
-Wno-long-long -m64 -g -D_DEBUG --coverage -Wl,-Bsymbolic -Wl,--
no-undefined -shared -o GPS2KML.plb CMakeFiles/GPS2KML.dir
/gps.cpp.o CMakeFiles/GPS2KML.dir/kml.cpp.o CMakeFiles/GPS2KML.dir
/stdafx.cpp.o /trunk/src/filter/GPS2KML/external/libkml/lib/cmake
/libkml/../../libkmlconvenience.so.1.3.1 /trunk/src/filter/GPS2KML
/external/libkml/lib/cmake/libkml/../../libkmlengine.so.1.3.1
/trunk/src/filter/GPS2KML/external/libkml/lib/cmake/libkml/../..
/libkmldom.so.1.3.1 /trunk/src/filter/GPS2KML/external/libkml
/lib/cmake/libkml/../../libkmlbase.so.1.3.1 -lminizip -luriparser
-lexpat
The make output:
CMakeFiles/GPS2KML.dir/kml.cpp.o: In function `cKML::~cKML()':
/trunk/src/filter/GPS2KML/src/kml.cpp:55: undefined reference to `*kmldom::SerializePretty(boost::intrusive_ptr<kmldom::Element> const&)*'
collect2: error: ld returned 1 exit status
Now if i do this:
daniyal#daniyal-Inspiron-5521:/$ nm --demangle --extern-only --defined-only ../trunk/src/filter/GPS2KML/external/libkml/lib/libkmldom.so | grep SerializePretty
It clearly shows:
000000000013c9aa T kmldom::SerializePretty[abi:cxx11](boost::intrusive_ptr<kmldom::Element> const&)
Now I fail to understand what is the problem. I have check the existing questions on stackoverflow regarding this, I found four solutions in the existing questions:
In some cases the demangled symbol name did not match with the symbol that was causing error. This is clearly not my case.
Use -llibrary at the end of the command after putting the name of the .o file. So that when the linker encounters the library it has an undefined symbol present in that library. This is clearly not a solution for me as I have the libraries present at the end of the command.
In some cases the symbol is present in the shared library but does not have external linkage or is not defined. This can be confirmed by using nm with --extern-only and --defined-only. And hence this is also not a solution for me.
Edit:
Additional Info:
This is the cmake file I am using:
find_package(LibKML REQUIRED)
include_directories(${LIBKML_INCLUDE_DIRS})
add_filter(${PROJECT}
gps.h
gps.cpp
kml.h
kml.cpp
#can2gps.h
#can2gps.cpp
stdafx.h
stdafx.cpp )
target_link_libraries (${PROJECT} ${LIBKML_LIBRARIES})
add_filter roughly translates to this macro:
add_library(${NAME} MODULE ${ARGN} ${${NAME}_MOC} ${${NAME}_UI} ${${NAME}_QRC})
target_link_libraries(${NAME} ${BUILD_LIBS} ${QT_LIBRARIES} ${ADTF_OPENGL_LIBRARY} ${ADTF_ADDITIONAL_UTILS_LIBS})
set_target_properties(${NAME}
PROPERTIES
SUFFIX ".plb"
)
if(UNIX)
set_target_properties(${NAME}
PROPERTIES
PREFIX ""
)
It looks like you have an ABI mismatch issue. ABI is "Application Binary Interface", basically the specification for exactly how arguments make it onto the stack (or are put in registers) and various other things like that.
Try making sure your code is compiled with the -std=c++11 (or -std=gnu++11 if you use any GNU extensions) flag. It looks like that's how libkml was compiled. C++11 has a bunch of new features that require an ABI compatibility break with pre-C++11. C++14 and C++1z are less drastic changes, but they may also break ABI compatibility, I'm not sure. In this case though, the demangled symbol is clear, libkml wants at least C++11.

Finding mangled C++ link error

There are two link errors in this project.
The first, pointed out by #Steve, is the lack of
void *__gxx_personality_v0;
If anyone can explain why a C++ project compiled with clang++3.5 under cygwin would create a reference to this, I would like to understand. Anyway, I defined the symbol as a workaround.
The other problem appears to be references to 32-bit relative addressing in 64-bit. I am looking for a way to tell clang++ to compile 32 bit or 64 bit. I will try on native linux as well, but again, if anyone can explain why this is happening, I would like to understand.
I am thinking it might be a static variable, located down low in the address space, being accessed by something on the stack, but again, clang is generating everything so as far as I can see, this is a bug in the compiler.
clang++ -std=c++11 -O2 -g -I include/ -pthread -c RequestHandler.cc
clang++ -std=c++11 -O2 -g Config.o Logger.o RequestHandler.o FileSys.\
o Buffer.o server.o CspServlet.o -pthread -o server
RequestHandler.o:fake:(.debug_info+0x54bd): relocation truncated to f\
it: R_X86_64_32 against `.debug_ranges'
...
FileSys.o:fake:(.eh_frame$_ZNSt10_HashtableISsSt4pairIKSsP2FLESaIS4_E\
NSt8__detail10_Select1stESt8equal_toISsESt4hashISsENS6_18_Mod_range_h\
ashingENS6_20_Default_ranged_hashENS6_20_Prime_rehash_policyENS6_17_H\
ashtable_traitsILb1ELb0ELb1EEEE21_M_insert_unique_nodeEmmPNS6_10_Hash\
_nodeIS4_Lb1EEE+0x13): undefined reference to `__gxx_personality_v0'
FileSys.o:fake:(.eh_frame$_ZNSt8__detail16_Hashtable_allocISaINS_10_H\
ash_nodeISt4pairIKSsP2FLELb1EEEEE16_M_allocate_nodeIJRKS6_EEEPS7_DpOT\
_+0x13): more undefined references to `__gxx_personality_v0' follow
collect2: error: ld returned 1 exit status
Ok, it turns out that on cygwin, when I installed clang, it doesn't fully use the clang toolchain. clang is compiling, but g++ is linking (I think). Bear in mind all these tools could be aliased to something else, but it's very suspicious.
I built on Unix and it worked. Same makefile.
So the problem is that when I wrote clang, it wasn't using clang to link. And that is weird.

How to cope with older library installed in `/usr/lib` by sysadmin

I have recently got an account on a supercomputer grid, and I'm trying to compile my code in theri system. Problem is that program won't link with following errors:
/mnt/opt/tools/slc6/binutils/2.22/bin/ld: warning: libboost_system.so.1.55.0, needed by /mnt/home/jbzdak/tools/boost_1_55//lib/libboost_thread.so, may conflict with libboost_system.so.5
/mnt/opt/tools/slc6/binutils/2.22/bin/ld: /mnt/home/jbzdak/tools/boost_1_55//lib/libboost_thread.so: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/mnt/opt/tools/slc6/binutils/2.22/bin/ld: note: '_ZN5boost6system15system_categoryEv' is defined in DSO /mnt/home/jbzdak/tools/boost_1_55//lib/libboost_system.so.1.55.0 so try adding it to the linker command line
/mnt/home/jbzdak/tools/boost_1_55//lib/libboost_system.so.1.55.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
Which is due to the fact that my program needs boost 1.55, and only 1.39 is instlled on the system in /usr/lib64. I have installed my version of boost in local folder, but somehow still system one is loaded first.
Here is excerpt from flags passed to the compiler:
-std=gnu++11 -Werror -Wall -lboost_thread -lboost_filesystem -lboost_system -lboost_iostreams -g -DG4OPTIMISE -Iinclude
-W -Wall -ansi -pedantic -Wno-non-virtual-dtor -Wno-long-long -Wwrite-strings -Wpointer-arith -Woverloaded-virtual -pipe -O2
full listing of flags is here (they should be irrevelant).
Here are revelant config variables:
LIBRARY_PATH /mnt/home/jbzdak/tools/boost_1_55/lib:
CPLUS_INCLUDE_PATH /mnt/home/jbzdak/tools/boost_1_55/include:/mnt/home/jbzdak/tools/geant4.9.6.3/compile/include/Geant4
LD_LIBRARY_PATH /mnt/home/jbzdak/tools/boost_1_55/lib:/mnt/opt/tools/slc6/gcc/4.8.3/lib64: ...
Directory /mnt/home/jbzdak/tools/boost_1_55 contains installed boost library.
I use GCC 4.8.3 with ld 2.22.
I have very little experience with linker errors hence the question. Is there any way to exclude boost libraries in /usr/lib64, or make the linker use locally installed libraries, and and ignore the system one?
I said in a comment:
There's no -L/alternative/location/of/boost/lib shown, so the compiler (linker) doesn't know it needs to look somewhere else for your modern Boost library. You may need -Wl,rpath,/alternative/location/of/boost/lib as well.
And the question was asked:
Why didn't LD_LIBRARY_PATH solve the issue?
Because LD_LIBRARY_PATH is a run-time variable rather than a link-time variable. It affects where the /lib/ld.so.1 (or equivalent) dynamic loader looks for libraries when you run a program, not where the linker looks to find its libraries.
After some additional debugging and asking another question, I found out the root cause of problem. Any -L parameter has precedence over LIBRARY_PATH and somehow -L/usr/lib64 was added (hence it had precedence over my version).
To check what options are sent to gcc pass -v parameter.

Linking errors with "-Wl,--no-undefined -Wl,--no-allow-shlib-undefined"

Using the flags "-Wl,--no-undefined -Wl,--no-allow-shlib-undefined" with GCC leads to the following compilation errors on the Travis CI image but not on my machine (both are Ubuntu 12.04 64-bits):
Linking CXX shared library libmocap.so
cd /tmp/_travis/build/src && /usr/bin/cmake -E cmake_link_script CMakeFiles/mocap.dir/link.txt --verbose=1
/usr/bin/g++ -fPIC --coverage -Werror -pedantic -Wno-long-long -Wall -Wextra -Wcast-align -Wcast-qual -Wformat -Wwrite-strings -Wconversion -fvisibility=hidden -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -shared -Wl,-soname,libmocap.so.0.0.0 -o libmocap.so.UNKNOWN CMakeFiles/mocap.dir/abstract-marker.cc.o CMakeFiles/mocap.dir/abstract-virtual-marker.cc.o CMakeFiles/mocap.dir/color.cc.o CMakeFiles/mocap.dir/link.cc.o CMakeFiles/mocap.dir/marker-set-factory.cc.o CMakeFiles/mocap.dir/marker-set.cc.o CMakeFiles/mocap.dir/marker-trajectory-factory.cc.o CMakeFiles/mocap.dir/marker-trajectory.cc.o CMakeFiles/mocap.dir/marker.cc.o CMakeFiles/mocap.dir/mars-marker-set-factory.cc.o CMakeFiles/mocap.dir/math.cc.o CMakeFiles/mocap.dir/pose.cc.o CMakeFiles/mocap.dir/segment.cc.o CMakeFiles/mocap.dir/string.cc.o CMakeFiles/mocap.dir/trc-marker-trajectory-factory.cc.o CMakeFiles/mocap.dir/virtual-marker-one-point-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-relative-to-bone.cc.o CMakeFiles/mocap.dir/virtual-marker-three-points-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-three-points-ratio.cc.o CMakeFiles/mocap.dir/virtual-marker-two-points-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-two-points-ratio.cc.o
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_dl_argv#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_rtld_global_ro#GLIBC_PRIVATE'
/usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so: undefined reference to `__tls_get_addr#GLIBC_2.3'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_rtld_global#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `__libc_enable_secure#GLIBC_PRIVATE'
collect2: ld returned 1 exit status
make[2]: *** [src/libmocap.so.UNKNOWN] Error 1
Strangely, this does not occur on my machine and hence is a bit difficult to reproduce.
What is the right way to link against the libc and libstdc++ when these flags are enabled?
(as you might guess from the output, I use CMake to generate the compilation command)
The default for the 2nd argument is "--allow-shlib-undefined".
Probably if you choose that option the code will build.
This 2nd argument deals with build time checking where enabling this means checking that the library that you are linking against in turn has its dependencies wired up at build time.. And that is not necessarily the case.
The first argument makes sure that you have not forgotten to state a dependency to a runtime library (which may also be a dependency that a runtime library has to another runtime library).For example if you are calling a function where the implementation is in an example runtime library "libfunc.so" and that library in turn will call a function in another runtime library "libext.so" then by declaring a dependency to both "func" and "ext" the libfunc.so will be generated to internally include a dependency reference to libext.
If you would leave out "--no undefined" and forget to add dependency declarations then the build would still succeed, trusting that your runtime linker would resolve dependencies at runtime. And since the build was successful you might trust that everything will be ok not knowing that the build has deferred responsibility to the runtime linker. But most often the runtime linker is not designed to search for unresolved references but expects to find such dependencies stated in the runtime library. And if no such reference is there you will get a runtime error. Runtime errors are typically much more costly than resolving a compile time error.