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

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.

Related

Static linking libc++ clang

I trying to link statically the standard library libc++ (https://libcxx.llvm.org/) in Linux (Arch using this AUR https://aur.archlinux.org/packages/libc%2B%2B/) using Clang.
I get the error /usr/bin/ld: cannot find -lc++
The error is independent from the code, it appears even in a "Hello World".
If I remove the -static option it compiles (and links) and the generated executable works.
I don't want to use libstdc++ (I have my reasons not to please not focus the discussion in this) and the linking must be static (it's a requirement).
I'm perfectly aware that it's difficult to debug this stuff without having access to the machine where it happens. However, it happens it two different machines (both with Arch) so maybe it's something I'm forgetting about.
What I have tried so far is explained here (https://releases.llvm.org/7.0.0/projects/libcxx/docs/UsingLibcxx.html)
The basic command that shoud work it's the following
clang++ -static -stdlib=libc++ -std=c++17 main.cpp -lc++abi
That will be because you do not have a static libc++ (i.e. libc++.a) installed
on your system. Archlinux defaulted to not installing static libraries 5 years ago,
so it will be challenging for you to perform fully static linkages. You will
have to make your own static builds of all dependent libraries, recursively.

Linking to system Eigen failing with undefined references in emmintrin.h

I'm having a problem at the link stage of compiling an application that links to several user built libraries.
These libraries link to the system Eigen 3 install, and all libraries were built using the same compiler and flags (gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)) This is on a RHEL 7.3 system (large cluster that uses module system to load/unload compilers).
What's strange is I built many other applications that linked to these same libraries that link to Eigen. All compile and link fine. This one application (not my code, but depends on same libs), is compiling fine but then spewing errors like this:
/usr/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h:114: undefined reference to `_mm_set1_pd'
/nas/longleaf/home/deleeke/dogwood/sfw/ibamr/ibamr-master-scorep/ibtk/lib/libIBTK3d.a(libIBTK3d_a-LEInteractor.o): In function `double __vector Eigen::internal::pset1<double __vector>(Eigen::internal::unpacket_traits<double __vector>::type const&)':
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/emmintrin.h:64: undefined reference to `_mm_set1_pd'
But this function is indeed defined in the emmintrin.h file it is pointing to. I know this header has something to do with instruction sets, but that's the extent of my knowledge.
I have not found any resources in my online searches or even going to the sysadmin's who run this cluster I'm working on. They all just groan a little bit and wave their hands around.
I know this code compiles on other machines -- so it has me thinking it has something to do with libgcc?
Can anyone give me some tips on how to trouble shoot this?
Thanks!

What determines if a 32-bit library built on a 64-bit machine needs x86_64 or i386 dependencies?

I am updating some old C++ projects to build on a 64-bit Linux machine for the first time, and I don't have much Linux experience. I need to build everything as 32-bit binaries, so I'm building everything with -m32 in the compiler and linker flags. I'm finding that, when linking to their dependencies, some must link with i386 shared objects, and some must link with x86_64 shared objects. If I only include the wrong folder in the linking path (-L/path/to/wrong/folder), it says
/usr/bin/ld: skipping incompatible xxx.so when searching for -lxxx
which I've come to understand means the architecture doesn't match what I'm trying to build.
The makefiles are nearly identical for two such differing projects, so it doesn't seem like I'm doing something obviously wrong there, and -m32 appears in the calls to gcc and g++ in the terminal. What could be causing this difference? Should I be concerned, or is it typical for this to happen?
Let me know if more information is needed to answer; I'm not really sure, due to inexperience with Linux and gcc, so apologies in advance.
Thanks #Wyzard and #duskwuff for the tips. I was indeed able to find my problem by using file on my .o files. It was just a silly mistake; I had inadvertently reverted the changes I made to one of the projects' make files, which included adding the -m32 flag. I think I misunderstood what the "x86_64" libraries are for, and that confused me (I had assumed it meant "32-bit process for 64-bit machine").

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

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.

compile against libc++ statically

I wrote some custom c++ code and it works fine in ubuntu, but when I upload it to my server (which uses centos 5) its fails and says library is out of date. I googled all around and centos cannot use the latest libraries. How can I compile against the stl so that it is included in the binary and it doesn't matter that centos uses an old library?
P.S. I don't want to upload the source to the server and compile there.
In your linking step, you can simply add the "-static" flag to gcc:
http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Link-Options.html#Link-Options
You may install on your Ubuntu box the compiler that fits the version of the library on your server.
You may ship your application with libstdc++.so taken from the system you compiled it at, provided you tune the linking so it gets loaded instead of centos' one.
You may compile it statically. To do this, you should switch your compiler from g++ to
gcc -lgcc_s -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
Choose whatever you like. Note that approaches (2) and (3) may arise the problem of dependencies: your project (particularly, the stdc++ implementation that, being statically linked, is now a part of your app) may require some functions to present in the system libraries on centos. If there are no such functions, your application won't start. The reason why it can happen is that ubuntu system you're compiling at is newer, and forward compatibility is not preserved in linux libraries.