Link AMD acml in Linux - linux

I need to link AMD acml library in a C++ project.
I tried to compile it in this way:
g++ mainConsole.cpp -L./acml/pgi64_int64/lib -lacml
but I get this error:
/usr/bin/ld: skipping incompatible ./acml/pgi64_int64/lib/libacml.so when searching for -lacml
/usr/bin/ld: skipping incompatible ./acml/pgi64_int64/lib/libacml.a when searching for -lacml
/usr/bin/ld: cannot find -lacml
What can I do in order to solve?

It seems the linker was told to use a 64 library when the compilation was done using 32 bits.
Your call to g++ will both compile and link. It's easier to debug if you split both. For example:
g++ -I./acml/pgi64_int64/include mainConsole.cpp -o mainConsole.o
g++ -L./acml/pgi64_int64/lib -lacml mainConsole.o -o mainConsole
You can verify the library using file. On my system I get:
$ file /usr/lib/acml/gfortran/libacml.so
/usr/lib/acml/gfortran/libacml.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
The compiled object should be the same:
$ file mainConsole.o
mainConsole.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
The problem is either 32 bits compilation of your own project, or more probably your use of the "int64" verison of ACML. You can read more on int64 here. I suggest you try with the non-int64 version of ACML. For example, instead of downloading acml-5-3-1-pgi-64bit-int64.tgz, download acml-5-3-1-pgi-64bit.tgz.

Related

Can't link shared library with -mx32 and gcc 4.7 or gcc 4.8

I'm trying to compile a large codebase written for a 32 bit embedded processor to run on a 64 bit desktop processor for simulation/unit testing. I need the resulting object to be a shared library. This is not an issue in Windows, I can build a dll like this (/DWIN32) and it runs fine.
In Linux, I'm able to compile and link with the -m32 option given to both gcc and the linker and get a shared library out. The problem is, this library is (just like I specified with -m32) a 32 bit library and will not run on my 64 bit arch. With Python, I try to load the library (using ctypes.cdll.LoadLibrary())
OSError: out.so: wrong ELF class: ELFCLASS32
I discovered the -mx32 option, and according to the docs this is exactly what I want:
The -mx32 option sets int, long, and pointer types to 32 bits, and
generates code for the x86-64 architecture.
So, I pass -mx32 to the compiler and the linker (replacing my -m32 option) and get the following (snipped the output):
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.a when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: cannot find -lm
I get the same results with gcc 4.7 and gcc 4.8. The above output is from gcc 4.8.
I have gcc-4.8-multilib and g++-4.8-multilib installed.
My library path is:
LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/
From .bashrc I've specified it like this (below), in despair adding the /4.8/ and /4.8/32/ stuff after reading that the linker would only bind with the libraries that work.
export LIBRARY_PATH=/usr/lib/$(gcc -print-multiarch):/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/
As I mention, this works quite well already on Windows as a dll, I have to believe I'm just missing something. Pointers should be 32 bits and longs should be 32 bits, the whole thing should run on x86_64. -mx32 says it will do exactly that (right?).
Checking one of the objects after compiling in -m32:
$:~/project$ file foo.o
foo.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
And checking the same object after compiling with -mx32:
$:~/project$ file foo.o
foo.o: ELF 32-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Am I going about this the wrong way? Can I still use my 32-bit shared library with some sort of compatibility layer?
I saw a bug report against gcc 4.7 regarding these link errors... But I didn't see much conclusion from it. This page says that gcc 4.8 is the recommended minimum for x32, so I installed it. Still -- I can't get it to link. -m32 links fine.
-m32 is normal 32-bit mode, and yes most x86-64 GNU/Linux systems have multiarch support with 32-bit libraries that you can install if not already installed.
The -mx32 option is not what you want at all. It compiles code for the x32 ABI, which uses 32-bit addresses with 64-bit registers and instructions. The resulting code is not compatible with 32-bit processors (as it uses 64-bit instructions), but is also not compatible with 64-bit code (which will use 64-bit addresses). So everything in user-space has to be compiled with it in mind, including libc, and even the kernel needs to support x32 user-space and syscalls: https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use (i.e. just like supporting 32-bit binaries, x32 is effectively a separate architecture.)
Complicating matters further, the testing you've been doing on Windows hasn't been doing what you think at all. Passing /DWIN32 to the Visual C++ compiler only defines a macro called WIN32 (like -DWIN32 would for GCC); it doesn't make the compiler generate 32-bit binaries. 64-bit Windows executables cannot load 32-bit libraries; the libraries you've been testing with have actually been 64-bit.
If you want to unit-test 32-bit code, you'll need to test it on a fully 32-bit target architecture like -m32. x32 is not such a system. (32-bit code under a 64-bit kernel is fine, though, unless you're worried about only having 2G or 3GiB of address-space usable by user-space in your embedded system, instead of 4GiB under a 64-bit kernel.)
Your initial error, trying to load the library you successfully built, indicates that you are NOT using a 32-bit version of Python, so it can't build the 32-bit shared library.
If you install an i386 (32-bit) version of Python it should be able to load the library. What's more, that is the version of Python you'll need to run on your embedded i386 target.
Note that all the above assumes your "32bit embedded processor" is i386 compatible. If its not (its an ARM or MIPS or some other 32bit embedded processor instead), you'll need to install cross compilers for that target to build your library and an emulator (such as QEMU) to run executables.

Can't link to specific OpenSSL library (Linux Mint 13)

OpenSSL doesn't work well with valgrind unless you build it with a particular option so I've build OpenSSL again so that I can debug a program easily. The problem is, every time I build the program it links to an OpenSSL library I do not want. My makefile prints out a lot but the two lines that are most important are:
cc /usr/local/ssl/lib/libcrypto.so.1.0.0 /usr/local/ssl/lib/libssl.so.1.0.0 -L/opt/local/lib -shared -o bin/libcbitcoin-crypto.2.0.so build/CBOpenSSLCrypto.o
cc build/testCBNodeFull.o -L/home/matt/Desktop/cbitcoin/bin -lcbitcoin.2.0 -lcbitcoin-network.2.0 -lcbitcoin-storage.2.0 -lcbitcoin-threads.2.0 -lcbitcoin-logging.2.0 -lcbitcoin-crypto.2.0 -lcbitcoin.2.0 -lcbitcoin-file-ec.2.0 -lcbitcoin-rand.2.0 -L/opt/local/lib -lpthread -levent_core -levent_pthreads /usr/local/ssl/lib/libcrypto.so.1.0.0 -o bin/testCBNodeFull
As suggested elsewhere I'm specifying the precise location of the OpenSSL library I want. However ldd bin/testCBNodeFull gives me this:
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
There is apparently nothing wrong with the library I want to link to:
$ file bin/testCBNodeFull
bin/testCBNodeFull: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xd9472ecc11e12dc66d165c807a5dbe31fd461cf2, not stripped
$ file /usr/local/ssl/lib/libcrypto.so.1.0.0
/usr/local/ssl/lib/libcrypto.so.1.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xb75602dc478ae55576e21aac5251b915b1653e73, not stripped
Both compiled as x86-64 as you can see. Maybe there is a tool that allows me to change the location of the shared library of the executable?
Shared libraries are loaded at runtime, not compile time. So, you need to tell valgrind which OpenSSL library you want it to use at runtime. You can do this by setting the LD_LIBRARY_PATH environment variable to the directory containing your rebuilt object.
export LD_LIBRARY_PATH=/home/matt/mylib
#now try ldd bin/testCBNodeFull

skipping incompatible libGL.so

I have freshly installed Fedora 19 x86_64 on my PC.
I wrote a simple OpenGL program, but failed to compile it.
gcc -o quad quad.c -lX11 -lGL -lGLU
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.8.1/../.. /../libGL.so when searching for -lGL
/usr/bin/ld: skipping incompatible /lib/libGL.so when searching for -lGL
/usr/bin/ld: skipping incompatible /usr/lib/libGL.so when searching for -lGL
/usr/bin/ld: cannot find -lGL
collect2: error: ld returned 1 exit status
I have MesaGL and other libraries in place (i.e. /usr/lib) then what's wrong ?
For me, something was wrong with the library symlinks:
$ locate libGL.so | egrep ^/usr | xargs file
/usr/lib/libGL.so: symbolic link to `/usr/lib/libGL.so.1'
/usr/lib/libGL.so.1: symbolic link to `/usr/lib/libGL.so.1.2'
/usr/lib/libGL.so.1.2: symbolic link to `/usr/lib/fglrx/fglrx-libGL.so.1.2'
/usr/lib/fglrx/fglrx-libGL.so.1.2: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
/usr/lib64/FGL.renamed.libGL.so.1.2.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=46121ec8b16424a8b65a0cf11c3f9730ae0e49f5, stripped
/usr/lib64/libGL.so: broken symbolic link to `libGL.so.1.2.0'
/usr/lib64/libGL.so.1: symbolic link to `/usr/lib64/libGL.so.1.2'
/usr/lib64/libGL.so.1.2: symbolic link to `/usr/lib64/fglrx/fglrx-libGL.so.1.2'
/usr/lib64/fglrx/fglrx-libGL.so.1.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
So /usr/lib/libGL.so pointed at a 32-bit lib and /usr/lib/libGL.so was a broken link. I fixed the /usr/lib64 version to point correctly at libGL.so.1 (and the /usr/lib version to point at the 64 bit version for good measure) and this seems to have gotten my code compiling.
There are warnings about incompatible versions of libGL, and also about incompatible GCC libraries. I think you might have a 32 bit version of gcc installed on a 64-bit OS. Try
file -L `which gcc`
to check on this.
The problem is fixed.
I removed ATI Catalyst Driver v13.6 beta by executing "aticonfig --uninstall"
REBOOT
compile the program with same commands, and it was success :)
Now I reinstalled ATI Catalyst Drivers v13.6 beta
REBOOT and compile the program again,
It builds SUCCESSFULLY !!
Don't know what was wrong, but I have OpenGL working now :)
Install freeglut-devel :
# sudo yum install freeglut-devel

g++ throwing file not recognized: File format not recognized error

getting following error with the command g++ -o test -L . -l pq
libpq.so: file not recognized: File format not recognized
#file libpq.so
libpq.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), not stripped
gcc version 4.1.2 20070115 (SUSE Linux)
I am getting the same error if I try to use -l dbodbc instead of -l pq.
Note that test.c is a simple hello world program.
Thanks in Advance.
file /usr/bin/g++ tells you that g++ itself is a 64-bit executable, i.e. it runs on a 64-bit machine, it doesn't tell you that g++ can compile 64-bit code (it's very unlikely but it could be a cross compiler for a completely different processor!) Use g++ -v or g++ -dumpmachine to find out what target it generates executables for.
G++ doesn't actually use that library, it just passes the -l option to the linker, so the error is coming from the linker, ld
If ld and objdump are both saying they can't recognize the library but the same file is fine on a different machine, I would try updating or reinstalling the binutils package, which provides both ld and objdump.
You might have a 32-bit binutils installed, so its ld and objdump wouldn't understand the x86_64 library. Ensure you have the 64-bit (i.e. x86_64) binutils RPM installed.

Shared Library file format not recognised

I am using a shared library. Which I am using it to cross compile my executable. During the linking stage linker throws the error file format not recognised.
When I run ld on it libcclass.so: file not recognized: File format not recognized
When I run file libcclass.so: it gives libcclass.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), not stripped
If you're cross-compiling an executable, you also need to cross-compile all of the shared libraries it depends on, and link against those. For example, you can't link an i386 executable to an x86_64 shared library.

Resources