dynamic library using boost has undefined references when built on ARM architecture - c++

I have a C++ based dynamic library that I have built for the big 3 OSs that relies heavily on boost. Currently, I am compiling it for the raspberry pi. It took me a while to find the magic words to get the library to even build (-frepo as a compiler flag was the key, but I confess that I am not certain why this is the case).
Now, when I try to link to the library, I get an 'undefined reference' error to every boost call that my library makes, i.e.:
//`libmylib.so`: undeifined reference to `boost::shared_ptr<boost::detail::thread_data_base>::shared_ptr()'
When I build libmylib.so, I also build a custom version of boost as libboost.a. This all compiles and links fine on other OSs and non-ARM architectures so I tried putting -lboost as one of the flags, but I still get the same plethora of undefined reference errors form libmylib.so.
Needless to say, all my paths are correct.
It seems like linking behaves a bit differently on the raspberry pi than it does on other linux systems. For example, I built a static library (libmythread.a) that uses libpthread. When I link to that libmythread.a, I also get undefined reference errors unless I also use -lpthread in the build recipe. On my Thinkpad running Fedora, I would never have to do this since I included -lpthread in the compilation of the static library libmythread.a.
I would love to find a tutorial or guide that explains these discrepancies. I would also love to overcome them!
I also tried the same build on a conventional linux machine and everything linked fine, no problem. At least I know that my build process is OK. This does open up the possibility, though, that the -frepo flag is doing something funny that I don't understand and that this could be the root of the problem.

Solved. In the end, the trouble stemmed from the -frepo flag. This was necessary to compile a file called legacy_abi.cpp that is part of my library to allow third party developers using older and more exotic OSs/compilers. This isn't needed on the Pi, so I just removed it from the offending file from the build, dropped the -frepo flag and happy happy.
One final note, aptitude (for Pi, anyway) only supplies boost up to 1.49 (as far as I can tell). My project requires boost >= 1.50. This is an inherited project, so I'm still discovering all its little idiosyncracies.

Related

Cross Compiling from Linux-Windows, stdio has undefined references (to __imp___acrt_iob_func)

As the title says, I've been trying to cross compile a fairly large project with quite a few dependencies (both static and dynamic libraries). I've cross compiled every dependency successfully using MinGW-w64, set the include & library search paths to their MinGW counterparts (/usr/x86_64-w64-mingw32/lib & include), and yet on the linking step MinGW throws out an error for each call of printf (with stdio.h included, of course). The errors are as follows:
/usr/bin/x86_64-w64-mingw32-ld: ./obj/XXXX.o:/usr/share/mingw-w64/include/stdio.h:352: undefined reference to `__imp___acrt_iob_func'
(Where "XXXX" is a file name from my project)
This error is repeated the exact same (with the exception of the object file name). The command for linking looks like this:
/usr/bin/x86_64-w64-mingw32-g++ -o bin/ReleaseWin/Project #[file with object file names] -L. -L/usr/x86_64-w64-mingw32/lib/ [linking some dependencies (boost, openGL, SDL2, etc.)...] -m64 -flto
I've searched for a solution (or even someone with the same problem) to no avail. I've never been well-versed in linking any more than regular libraries, so if you need more information just ask.
Thanks in advance :)
Extra info:
This project has been cross compiled (from Linux to Windows) successfully before, and I haven't added/removed any dependencies since.
My MinGW-w64 version is 7.0.0
So, I apt-get purge'd mingw-w64 and mingw-w64-common, reinstalled just mingw-w64, and now it's working...
This might have something to do with the fact that I followed the issue that Richard Critten commented with (thanks!), which led me to try downloading and manually copy/pasting headers and CRT (mingw-w64-x86_64-headers-git-... & mingw-w64-x86_64-crt-git) from the MSYS2 repository. That didn't work right away (probably because I screwed up and used the 5.0.0 versions instead of my version), but it seems to have done something.
Therefore, for those who stumble upon this issue,
Try a re-install of MinGW (of course),
Try manually adding the CRT and headers from the link I supplied, and if that still doesn't work,
Try re-installing MinGW again. I'm not super familiar with apt, so I don't know if adding the CRT and headers actually changed how it installed MinGW, but it's worth a shot I guess.
Update: I had this exact same problem on another system. Simply reinstalling MinGW fixed it, so it seems like maybe there was some sort of issue with the files? It's possible that updating from an earlier version messed with things. Moral of the story: even if you think your files are good, a reinstall can't hurt.

Man Bites Dog: symbol resolved *without* linking library? clock_gettime() -lrt

I have a C++ source tree developed under Ubuntu 12.04 using clang++ 3.2 that builds some libraries, then compiles some applications with these libraries and the usual collection of other various system libraries. Two puzzles. Client reports that code fails to build with undefined reference to clock_gettime(). Sure enough, I did not include the obligatory "-lrt" in the build logic (scons).
First puzzle: This compiles, links and executes correctly and without complaint on my system even though I do not specify "-lrt" anywhere! How does this symbol get correctly resolved? I suspect it is because the application links against a dynamic library that itself requires librt but I don't understand the logic behind why this would happen?
Second puzzle: Assuming a satisfactory explanation of how clock_gettime() gets resolved without "-lrt", why would this happen on my system but not on client's very similar setup?
"... a riddle, wrapped in a mystery, inside an enigma" --- Winston Churchill
Suggestions for tools to reveal what is really going on here would be most welcomed.
From SUSv4 (Utilities/c99):
-l rt
This option shall make available all interfaces referenced in <aio.h>, <mqueue.h>, <sched.h>, <semaphore.h>, and <spawn.h>, interfaces marked as optional in <sys/mman.h>, interfaces marked as ADV (Advisory Information) in <fcntl.h>, and interfaces beginning with the prefix clock_ and time_ in <time.h>. An implementation may search this library in the absence of this option.
I presume the above suffices to at least justify why this behavior is allowed by POSIX.
Most likely the involved systems are different in this regard. For example, clock_gettime() might be implemented in libc for you, but in librt for your client. Don't take chances: use a portable -l rt and forget about the issue.
A more obvious example is -l xnet, which behaves similarly according to POSIX, but, at least on Gentoo, Debian and Ubuntu Linux systems, compiling with -l xnet actually yields an error. (libxnet purportedly contains the implementation for the UNIX sockets interface.)
If you want to further investigate the issue, try ldd in GNU/Linux systems. ldd should display the dynamic dependencies for your binary. I'd bet that clock_gettime() is simply implemented in libc.so.

Problem linking c++ code using boost with mingw

I'm trying to port/build some of my code written for gcc (on linux) as a dll on windows. First I tried to build in under VC++ but there were so many errors/warnings (mainly in VC's own include files, which didn't really make much sense to me :)) so I installed MinGW distro (which includes Boost libraries). Compilation went quite smoothly, however linking failed with undefined references to functions from boost libraries. The "-t" parameter showed that the linker doesn't actually use the boost libraries for some reason (yes, the -L path is correct, the libraries are there, linker doesn't complain when I use -l).
After much googling I found out that the order is the problem, that I have to place my -l parameters after all my .o files (because of dependencies). This seemed to solve all the problems except one undefined reference to thread library. Again -t showed that this library is actually not used by the linker (not in the list) the others are (I use boost_system and boost_date_time as well). I played with the order of the parameters again but the result was the same. Any idea what am I missing?
The error is:
c:/x5/cpp/build//timed_cond.o:timed_cond.cpp:(.text$_ZN5boost6detail24basic_condition_variable7do_waitINS_11unique_lockINS_5mutexEEEEEbRT_NS0_7timeoutE[bool boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> > (boost::unique_lock<boost::mutex>&, boost::detail::timeout)]+0x246): undefined reference to `_imp___ZN5boost11this_thread18interruptible_waitEPvNS_6detail7timeoutE'
I use same versions of Boost library (1.44.0) on both platforms
Ok, I found the answer. Looks like the problem is in boost libraries being static in MinGW-distro. Normally they are configured to be linked dynamically and that caused above issue. This answer explains it...

Problems linking static Intel IPP libraries on Linux with g++

I've been trying to move a project over from Xcode to Linux (Ubuntu x86 for now, but hopefully the statically-linked executable will run on an x86 CentOS machine? I hope I hope?). I have the whole project compiling but it fails at the linking stage-- it's giving me undefined references for all functions defined by IPP. This is probably something really small and silly but I've been beating my head over this for a couple days now and I can't get it to work.
Here's the compile statement (I also have a makefile that's generating the same errors):
g++ -static
/opt/intel/ipp/6.0.1.071/ia32/lib/libippiemerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippimerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippsemerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippsmerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippcore.a
-pthread -I /opt/intel/ipp/6.0.1.071/ia32/include
-I tools/include -o main main.cpp pick_peak.cpp
get_starting_segments.cpp
get_segment_timing_differences.cpp
recast_and_normalize_wave_file.cpp
rhythm_score.cpp pitch_score.cpp
pitch_curve.cpp
tools/source/LocalBuffer.cpp
tools/source/wave.cpp distance.cpp
...and here is the beginning of the long list of linker errors:
./main.o: In function `main':
main.cpp:(.text+0x13f): undefined reference to `ippsMalloc_16s'
main.cpp:(.text+0x166): undefined reference to `ippsMalloc_32f'
main.cpp:(.text+0x213): undefined reference to `ippsMalloc_16s'
Any ideas? FWIW, these are the IPP dependencies in my Xcode project that builds, links, and runs without a problem: "-lippiemerged",
"-lippimerged",
"-lippsemerged",
"-lippsmerged",
"-lippcore",
Thanks!
Your linking problem is likely due to the fact that your link line is completely backwards: archive libraries should follow source and object files on command line, not precede them. To understand why the order matters, read this.
Also note that on Linux statically linked executables are significantly less portable than dynamically linked ones. In general, if you link system libraries dynamically on an older Linux system, it will work on all newer systems (I use ancient RedHat 6.2, and I haven't seen a system on which my executable will not run). This is not true for completely static executables; they may crash in all kinds of "interesting" ways when moved to a system with a different libc from the one against which they were linked.
I had problems with linking code with the v 6 of the ipp; using the v11 version of the compiler (with the included updates to the ipp) mysteriously fixed them. Granted, that was with a windows platform, but I was getting 8u versions of functions to compile and no 32f versions, despite both being listed as valid in the documentation.

Including boost::filesystem produces linking errors

Ok first off, I am linking to boost_system and boost_filesystem.
My compiler is a custom build of MinGW with GCC 4.3.2
So when I include:
#include "boost/filesystem.hpp"
I get linking errors such as:
..\..\libraries\boost\libs\libboost_system.a(error_code.o):error_code.cpp:
(.text+0xe35)||undefined reference to `_Unwind_Resume'|
..\..\libraries\boost\libs\libboost_system.a(error_code.o):error_code.cpp:
(.eh_frame+0x12)||undefined reference to `__gxx_personality_v0'|
Which after a little searching I found is most commonly when you try to link a C++ program with gcc, the GNU C compiler. But I printed out the exact build command that Code::Blocks is running, and it is definitely linking with g++.
If I comment out this include, everything works fine.
Any ideas? Also, as a side, anyone know of a good place to get windows binaries for boost? The build system is giving me issues, so I'm using some binaries that came with this custom MinGW package
Ok, I found the problem. It's a bit convoluted.
GCC is gradually becoming more IS 14882 compliant in the 4.x branch. As they go on, they are removing deprecated non-standards complaint features.
While 4.1.x seem to only have them deprecated and not removed, 4.3.x seems to actually have them removed. What this means is 4.3.x and greater have some backwards compatibility issues with things compiled in the 3.x branch (which used the deprecated and now removed features)
I was using a mix and match combination of binaries that had been compiled with GCC 3.x, 4.1.x and 4.3.x so no matter which one I used, I got a similar error, because at least one binary I was linking to was incompatible with the compiler I was trying at the moment.
I'm now using GCC 4.1.2 and most of my binaries have been compiled with it. I am still how ever using a few binaries from 3.x, which is why I am not upgrading to 4.3.x just yet.
Hope that was less confusing to read than it was to write...
This seems to be a good post addressing some of the issues as they were with 4.1.x
Windows binaries: www.boost.org - see the "Getting Started" page - but if you're using g++ on MingGW you don't want those. A simple way to understand it is, MingGW is like an operating system inside an operating system so really you're not actually using Windows. The ones you've got are probably right.
Not sure what's going on with your code though, sounds like the lib files aren't linking in properly somehow. Boost names its lib files by themselves so you don't actually name them explicitly, but you have to have the lib files for boost on the right path (and make sure they're installed/built too, which they might not be). I'm not sure how to get them on the right path with g++ because I haven't used MingGW, I've only used boost with Visual Studio.