Statically linking to a dynamic library. glibc - gcc

So. I have a problem where I have two versions of GCC on a machine.
3.4.6 and 4.1
This is due to some dependency issues with a new piece of software. (requires glibc 4.1)
When I go to link this new software with the 4.1 libraries it links fine. However, when it comes to executing the software it can't find the library, because it is looking at 3.4.6 in my LD_LIBRARY_PATH. If I set LD_LIBRARY_PATH to the 4.1 lib it blows up the shell,among killing other things, because the 3.4.6 libraries are used for that.
Its a bit of a catch 22.
Is there any way that at link time I can give an absolute path to that shared library without using the LD_LIBRARY_PATH?
This way I can hopefully have both versions, but only use 4.1 for this specific application?

You mean an absolute path that's used when the program is started and that's favored when looking for libraries? rpath is exactly that. It will overwrite the default search path and stuff set in LD_LIBRARY_PATH. Just tell gcc to pass it through to the linker:
g++ -Wl,-rpath,/usr/lib/my_4.1 -omy_binary *.cpp
You can make it show you the search processing (use help to make it give you more options):
[js#HOST2 cpp]$ LD_DEBUG=libs ./a.out
5859: find library=libc.so.6 [0]; searching
5859: search path=/usr/lib/my_4.1/tls/i686/sse2:/usr/lib/my_4.1/tls/i686:
/usr/lib/my_4.1/tls/sse2:/usr/lib/my_4.1/tls:
/usr/lib/my_4.1/i686/sse2:/usr/lib/my_4.1/i686:
/usr/lib/my_4.1/sse2:/usr/lib/my_4.1 (RPATH from file ./a.out)
5859: trying file=/usr/lib/my_4.1/tls/i686/sse2/libc.so.6
5859: ....
5859: search cache=/etc/ld.so.cache
5859: trying file=/lib/libc.so.6 (note: found here!)
5859:

not really an answer to your question, but an alternate solution:
you should be able to fix up your issues by adding your new lib path to /etc/ld.so.conf and running ldconfig as root.

Can't you set LD_LIBRARY_PATH just for the application that needs it?
I.e. instead of setting it globally as an exported variable, run your program as
LD_LIBRARY_PATH=/path/to/4.1/libs my_executabel
?
-k

Related

setting environment variables for LLVM on OS X

I am learning to build a compiler using LLVM as back end.
I followed the steps on getting started with the LLVM system until setting up your environment
What is the specific location for [/path/to/your/bitcode/libs] ?
Was this mistake cause the command not found when I type in lli in a Terminal?
//I am trying to build a hello world to see through the total compiling procedure
You can put LLVM_LIB_SEARCH_PATH wherever you want. For now, you probably don't need to worry about it at all; as the documentation says, it is optional. Later, you may create bitcode (i.e. compiled VM code) functions which you would like to link into the bitcode your compiler produces. For example, you may need to create some kind of standard library and runtime environment for your executables.
That has nothing to do with the lli not found error, which is the result of the LLVM binaries either not having been installed, or having been installed somewhere which is not in your $PATH.
By default, the llvm package will configure itself for installation under the prefix /usr/local, which means that after you gmake install you should find lli and friends in places like /usr/local/bin/lli. That may or may not be in your $PATH; to find out, type
echo "$PATH"
and see if it has :/usr/local/bin: somewhere in it. If it doesn't, then you could change your PATH:
export PATH="/usr/local/bin:$PATH"
To make that permanent, you'll have to add it to your bash startup files.
But you might not want it to be installed there. I usually install software I'm playing with in my local directory tree, so that I don't have to sudo all the time. You can change the root of the installation directory tree with the --prefix argument to ./configure. (You have to do that before you build LLVM.) ./configure --help will provide some more information about configure options, but --prefix is certainly the most important one.
Whatever you do, don't do it blindly. Make sure you understand what this all means before doing it. If you plan on making a compiler, you'll need to understand some of the details of a typical build- and runtime- environment; PATH and configure scripts are on the unfortunately long list of things you should at least be somewhat familiar with.
As I understand it, some version of LLVM is already installed on Mac OS X, so you'll need to be careful that your installation doesn't interfere. The fact that bash is report that lli can't be found probably indicates that not all the tools are installed, which will make things less complicated.
I'm afraid that I don't really have any experience with installing LLVM on a Mac, but if you run into specific problems (like "my compiler doesn't work after I install LLVM") then you could ask a specific question with appropriate tags.

Is there a typical way to disable manpages generation using autotools?

I am compiling an old version of GNU coreutils(version 6.10/6.11) using autotools. However when I do some modifications in the source code directory there will be some errors when generating man pages.
As I don't care about the manpage at all, I hope the default target doesn't include manpage's generation.
There might not be a general solution for all kinds of source code managed by autotools, however I believe there must be a typical approach, especially for GNU coreutils.
Any advice will be appreciated:-)
Regarding installation:
At least for projects like Libssh2 and LibCurl, you can just do a make install-exec instead of make install.
Conversely, if you just want the man pages, you should do a make install-data.
I am not sure if these targets exist in every autotools project though.
I don't think building manpages is a built-in task of any sort. I believe it is usually just a subdirectory or specific target that is being run. You can probably just find the part of the Makefile.am responsible for building the man page and disable it. Either by removing the SUBDIR entry for the directory or by removing whatever target references the manpages target.
The error is due to the correct path for manpages not being found ,which will be mostly docbooks.xsl (as it is for me). So find the docbooks path
find /usr -name docbooks.xsl
This will list all available paths related to docbooks.xsl.
Find the correct docbooks required by make and paste it in the file

USB GCC Development Environment with Libraries

I'm trying to get something of an environment on a usb stick to develop C++ code in. I plan to use other computers, most of the time linux, to work on this from a command line using g++ and make.
The problem is I need to use some libraries, like Lua and OpenGL, which the computers don't have. I cannot add them to the normal directories, I do not have root on these computers. Most of the solutions I've found involve putting things in /usr/lib/ and the like, but I cannot do that. I've also attempted adding options like '-L/media//lib', which is where they are kept, and it didn't work. When compiling, I get the same errors I got when first switching to an OS with the libraries not installed.
Is there somewhere on the computer outside of /usr/ I can put them, or a way to make gcc 'see' them?
You need more than the libraries to be able to compile code utilizing those libraries. (I'm assuming Linux here, things might be slightly different on e.g. OSX,BSDs,Cygwin,Mingw..)
Libraries
For development you need these 3 things when your code uses a library:
The library header files, .h files
The library development files, libXXX.so or libXXX.a typically
The library runtime files , libXXX.so.Y where Y is a version number. These are not needed if you statically link in the library.
You seem to be missing the header files (?) Add them to your usb stick, say under /media/include
Development
Use (e.g.) the compiler flag -I/media/include when compiling source code to refer to a non-standard location of header files.
Use the compiler/linker flag -L/media/lib to refer to non-standard location of libraries.
You might be missing the first step.
Running
For dynamically linked libraries, the system will load those only from default locations, typically /lib/ , /usr/lib/
Learn the ldd tool to help debug this step.
You need to tell the system where to load additional libraries when you're running a program, here's 3 alternatives:
Systemwide: Edit /etc/ld.so.conf and add /media/libs there. Run ldconfig -a afterwards.
Local, to the current shell only. set the LD_LIBRARY_PATH environment variable to refer to /media/lib, run export LD_LIBRARY_PATH=/media/lib
Executable: Hardcode the non-standard library path in the executable. You add this to the linking step when creating your executable: -Wl,-rpath,/media/lib
Etc.
There could be other reasons things are not working out, if so,
show us the output of ls -l /media/libs , and where you put the library header files, the command line you use to compile/link, and the exact errors you get.
Missing the headers and/or development libraries (for dynamic libraries there is usually a symlink from a libXXX.so to a libXXX.so.Y , the linker needs the libXXX.so , it will not look directly at libXXX.so.Y)
using libraries not compatible with your current OS/architecture. (libraries compiled on one linux distro is often not compatible with another distro, or even another minor version of the same distro)
using an usb stick with a FAT32 filesystem, you'll get in trouble with symlinks..

glibc Linux based

I am currently using ubuntu 9.10 with the glibc version 2.11.1-0,
well i am doing a project, that i want to test with the another version of glibc that is 2.5-58, i wanted to know following things regarding this:
How to compile the version of 2.5-58, however keeping the previous version?
How to link the existing programs with the binaries of newer version of glibc?
I would be highly obliged if anybody can help me!!!
Thanks
If you want to manually compile another version of glibc, then I suggest you configuring (./configure script run) it with --prefix option to install not to /lib, /usr/lib but to /home/mehul/glibc2.5.58test/lib and /home/mehul/glibc2.5.58test/usr/lib
But compiling of glibc is not very easy thing, so another way is to get glibc 2.5-58 in compiled form from other linux and manually copy it to some subdirectory. Then you can override library search path of gcc and recompile your lib with libc from subdirectory.
Or you can use LD_LIBRARY_PATH to override library search path of compiled binary to use older glibc like this:
$ LD_LIBRARY_PATH=/home/mehul/glibc2.5.58test/lib /path/to/your/application
If you know that that version of libc is used in an older ditribution, you could install that distribution in a chroot/scratchbox/kvm/qemu/livecd or other such system for testing and building. Or there may be some other build farm type solution. Then you'll have an authentic system to test on that will not mess up your up to date one. It'll also be repeatable if you keep that system image.
If this isn't about a specific older release, why on earth would you want to test against a specific very old libc?

How to force Boost to use rpath?

I have to build Boost outside the "usual" directory tree (i.e., /custom/dir instead of /usr), which is not that much of a problem: Just pass --prefix=/custom/path to ./runscript.sh / ./bjam, and there you go.
Or so I thought.
The problem is that some of the Boost libraries depend on each other, and - using the default build process going through ./bootstrap.sh / ./bjam - it seems that the --prefix path is not added to the library search path for the Boost libs, i.e. no -Wl,-rpath is applied. That means that Boost libraries depending on other Boost libraries cannot find those at runtime.
My application - linking those /custom/path Boost libraries - already fails at ./configure stage because libboost_filesystem.so cannot find libboost_system.so, even though I passed -Wl,-rpath=/custom/path/boost/lib to my own compiler line (i.e. the correct path to the Boost libs, I double-checked that libboost_system.so is there).
Now, to avoid heavy-handed methods like setting LD_LIBRARY_PATH, I'd like to build Boost in a way so that all the Boost libraries have the proper search path for the other Boost libs compiled into them. However, I was unable to find the proper procedure for that. Can anybody help me?
I needed to do this recently for another project, although I needed to use $ORIGIN to make the path relative to the location of boost's shared objects.
This required the following on a bash command line:
./b2 hardcode-dll-paths=true dll-path="'\$ORIGIN/../lib'" --prefix=$MY_PREFIX install
Figuring out the magic collection of characters to get that $ORIGIN placed correctly in the shared object took a bit of trial and error, so I hope writing the answer here helps others to avoid fumbling around with this.
You can add compiler & link options during build from the command line with:
bjam hard-code-dll-path=true dll-path=/custom/path
There's a FAQ item in the Boost Build docs about this (see B2 docs).

Resources