I have this error message while building the curl library:
libssl.a(s2_clnt.o): relocation R_X86_64_32 against `.rodata' can not
be used when making a shared object; recompile with -fPIC
I tried to use the -fPIC switch - nothing helps. The openssl library was before compiled without any error. make check passed as well.
Info: I am compiling curl against another version of glibc - the include path is provided in ./configure with the $CPPFLAGS and $LDFLAGS == -L/usr/glibc-2.22/lib [== this is the path to the new glibc version]
This error is thrown only when I compile it with the new glibc version.
You get this kind of error when one object is built with hidden symbols and another one isn't.
Since I see you're trying to link a .a archive file aka static library, I assume that static library was built with different hidden symbol options than what you're using with curl.
I think that you can also get this when one object is using PIC and the other one isn't. To fix that compile the static library and curl with the same PIC settings.
Here is the solution for the issue collection I had in the past days:
several make issues...
Related
Context: I'm using a linux toolchain (includes g++, other build tools, libs, headers, etc) to build my code with statically linked libraries. I want to ensure that I'm using ONLY libraries/headers from my toolchain, not the default ones on the build machine. I can use strace to see what g++ is doing (which libraries it is using) while it is compiling which would be helpful in a normal scenario - but my build system has many wrappers around g++ that hide all of the output.
Question: is there a way to obtain from a statically-linked binary any useful information regarding the library and header files which were used to create the binary? I've taken a look at the objdump tool but I'm not sure if it will help much.
Just pass -v to g++ or gcc at link time. It will show all the linked libraries. Perhaps try make CC='gcc -v' CXX='g++ -v'
More generally, -v passed g++ or gcc shows you the underlying command with its arguments because gcc or g++ is just a driver program (starting cc1, ld or collect2, as, ...)
By passing the -H flag to GCC (i.e. g++ or gcc) you can see every included header. So you can check that only the heanders you expect are included.
You cannot see what static library has been linked, because linking a static library just means linking the relevant object file members in it, so a static library can (and usually is) linked in only partly.
You could use the nm command to find names from such libraries.
If you can simply recompile, then there are ways (using some of the techniques that Basile explained) to get the headers and libraries (static or dynamic) but, unfortunately, there is no way to know which libraries were used after the compilation is complete.
I wrote a very simple ncurses program to be run in BusyBox environment. However, it seems like that I cannot get my program to compile with everything. I used:
g++ menu.cpp -ohello -lncurses --> Works fine
g++ -static menu.cpp -ohello -lncurses --> Undefined reference to SP (many times)
I found this question but it ignores linking to ncurses. I need a very single executable. My targeted environment is fixed, so I do not concern portability.
You should paste the exact compiler calls and the exact error messages that you are getting.
Do you have a static version of the ncurses library?
More importantly, do you have a static version of the ncurses library compiled for your target environment? For example your target environment may be using ulibc instead of glibc or it could even be a whole different platform (hint: tell us what your target platform is).
Are you certain that you are compiling with the right flags? The compiler flags that you are showing seem more suited to compiling an application for use in the build host environment...
I want to use CUDPP library in my project. I've downloaded sources from project page. Unfortunatly, when I ran "make", there was only static library build. I've looked into Makefile files and haven't found any dynamic lib configuration. I don't want to keep static library with the project - it's totally non-portable way.
My question is: how can I build .so dynamic library of CUDPP, without writing my own Makefile/compiling it manually? Maybe someone already did it?
EDIT: I've replaced "g++" with "g++ -fPIC", "gcc" with "gcc -fPIC" and "nvcc" with "nvcc -Xcompiler -fpic". When I unpack obj files from archive, and link them to shared lib, I've got no error. However, my application crashes at start, when linked with this library.
when you compile pass the flag -Xcompiler -fpic to nvcc. If you link against any cuda libraries make sure you've linked to the shared libs, otherwise you can't link it. Hopefully that's all you need.
Are you also using -shared to create the library? You shouldn't need to extract anything from an archive if it is working correctly.
If you run ldd on your executable it will show you what dynamic linking is required by the app and you can check that the -fPIC etc. worked correctly. Also make sure that the .so library is on your LD_LIBRARY_PATH (sorry if that's obvious, no harm in checking).
I am attempting to install an application. During compilation it fails with the following error:
/usr/bin/ld: cannot find -lemu
I have installed the libemu library, and it now currently resides in /opt/libemu/. However, when I try and compile my application the library is not found. Is there any way to correct this?
EDIT: It also looks like the make is resulting in:
It also looks like the make file is compiling with the following:
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions
build/temp.linux-x86_64-2.6/libemu_module.o
-L/opt/libemu/lib -lemu -o build/lib.linux-x86_64-2.6/libemu.so
I have tried setting my LD_LIBRARY_PATH to /opt/libemu, still doesn't work - fails with the error mentioned above.
You need to tell the linker where it is:
gcc stuff -L/opt/libemu -lemu
or:
gcc stuff /opt/libemu/libemu.a
where stuff is your normal compile/link options files etc.
You can also specify library paths in the LIBRARY_PATH environment variable:
LIBRARY_PATH=/opt/libemu
export LIBRARY_PATH
before you run your build. Yet another option is to see where gcc looks for libraries by running:
gcc --print-search-dirs
and put your library in one of the listed directories.
Edit: It is really not clear from your latest info what you are trying to build. Are you trying to turn a static library into a shared library? Most important - What is the exact filename of the library file you have copied into the /opt/libemu directory?
The environment variable LD_LIBRARY_PATH should include (but probably does not by default) /opt/libemu.
try running:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/libemu
make install
How can I link a shared library function statically in gcc?
Refer to:
http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/
You need the static version of the library to link it.
A shared library is actually an executable in a special format
with entry points specified (and some sticky addressing issues
included). It does not have all the information needed to
link statically.
You can't statically link a shared library (or dynamically link a static one).
The flag -static will force the linker to use static libraries (.a) instead of shared (.so) ones. But static libraries aren't always installed by default, so you may have to install the static library yourself.
Another possible approach is to use statifier or Ermine. Both tools take as input a dynamically linked executable and as output create a self-contained executable with all shared libraries embedded.
If you want to link, say, libapplejuice statically, but not, say, liborangejuice, you can link like this:
gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary
There's a caveat -- if liborangejuice uses libapplejuice, then libapplejuice will be dynamically linked too.
You'll have to link liborangejuice statically alongside with libapplejuice to get libapplejuice static.
And don't forget to keep -Wl,-Bdynamic else you'll end up linking everything static, including libc (which isn't a good thing to do).
Yeah, I know this is an 8 year-old question, but I was told that it was possible to statically link against a shared-object library and this was literally the top hit when I searched for more information about it.
To actually demonstrate that statically linking a shared-object library is not possible with ld (gcc's linker) -- as opposed to just a bunch of people insisting that it's not possible -- use the following gcc command:
gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so
(Of course you'll have to compile objectname.o from sourcename.c, and you should probably make up your own shared-object library as well. If you do, use -Wl,--library-path,. so that ld can find your library in the local directory.)
The actual error you receive is:
/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status
Hope that helps.
If you have the .a file of your shared library (.so) you can simply include it with its full path as if it was an object file, like this:
This generates main.o by just compiling:
gcc -c main.c
This links that object file with the corresponding static library and creates the executable (named "main"):
gcc main.o mylibrary.a -o main
Or in a single command:
gcc main.c mylibrary.a -o main
It could also be an absolute or relative path:
gcc main.c /usr/local/mylibs/mylibrary.a -o main
A bit late but ... I found a link that I saved a couple of years ago and I thought it might be useful for you guys:
CDE: Automatically create portable Linux applications
http://www.pgbovine.net/cde.html
Just download the program
Execute the binary passing as a argument the name of the binary you want make portable, for example: nmap
./cde_2011-08-15_64bit nmap
The program will read all of libs linked to nmap and its dependencias and it will save all of them in a folder called cde-package/ (in the same directory that you are).
Finally, you can compress the folder and deploy the portable binary in whatever system.
Remember, to launch the portable program you have to exec the binary located in cde-package/nmap.cde
Best regards
In gcc, this isn't supported. In fact, this isn't supported in any existing compiler/linker i'm aware of.