Compile with GCC and relocate the linked libraries - gcc

I have my soft.c and I compile it successfully and link it against /usr/lib/myLib.so.
Everything it's ok except for the fact that it's not what I'm looking for, i would like to manage the final path considered for the linking, in other words i want GCC to consider the library /usr/lib/myLib.so but I also want the final linking to be a relative path, kinda like ../myLib.so.
The usual scenario is
./soft linked to -> /usr/lib/myLib.so
I want
./soft linked to -> ../myLib.so
Obiviously I also need GCC to manage any cross referenced library, for example if /usr/lib/myLib.so is linked to other libs i want all the libraries involved to be relocated in the relative path so ../myLib.so can fully work from a relative path .
How to achieve that ?
Thanks.

You could include run-time search path information in the binaries, using the -rpath option to the linker (passed to gcc as -Wl,-rpath,.
Note that this is generally frowned upon by distribution maintainers, as there should be a single system-wide library search path so conflicts are caught early.

Related

How does gcc/ld find zlib.so?

I've used zlib for ages and never thought about the fact that it is named slightly unconventionally. While most libraries on Linux follow the naming convention of lib<name>.so for shared objects and lib<name>.a for archives, zlib is named zlib.so/zlib.a. My question is: how does gcc/ld know to look for zlib.so when I use -lz as a link flag?
I understand that for linking, gcc invokes ld, which searches for libraries in certain default paths and any path specified with -L, and it appends the lib and .so or .a. parts as necessary. Oddly, gcc's manual page for linking options only mentions that the linker can find archives; there is no mention of the .so extension. The man page for ld at least mentions both extensions, but still only mentions searching by prepending lib to the specified library name. How does ld know to add the lib after the z for zlib? I've never seen this happen to another library.
gcc has several different methods for linking libraries, shared or static. If you specify -lz, gcc is going to look for libz.so (possibly with some version bits between the libz and the .so, but the important part is the file name will start with libz and end with .so), or for libz.a (again, possibly with version info) if you are compiling statically, or as a fallback if the shared library does not exist. If you specify -lzlib it will look for libzlib.so (which is not the standard name - the package is often named zlib, but the library itself is libz). Another way of linking would be to not use the -l<lib> option, and just specify /path/to/zlib.so or -L /path/to zlib.so (or zlib.a if you want). In this case, the library doesn't have to have the lib prefix, but you would have to explicitly provide any version info, unless provisions are made for a symbolic link or something similar to provide the literal name zlib.so.
Applications can also load shared libraries at runtime via dlopen() and it's other associated functions, in which case the library can also be named whatever you want it to be (this doesn't work for static libraries, of course).
So, if the library you are looking at is actually called zlib.so, then it is not being found by gcc ... -lz, unless it just happens to be a symbolic link to libz.so (or vice versa, in which case gcc is really just using libz.so, which happens to have the same content as your zlib.so). However gcc might be using it if the build process explicitly names the library in the link stage (not using -l<lib>) or if your application loads it via dlopen() (but in that case, it's not really linked to your program - it's just loaded at run time).

linking and executable by hand without alternatives

I use gcc more than any other compiler, so I will shape my example with this compiler suite, but i have experienced this problem with almost all the suite that i have tried like gcc, mingw, clang and msvc.
gcc offers this flags:
-l you write the name foo, gcc will find a corrisponding library named libfoo
-L you append the path where the libs lives and gcc tries to match the required libraries to the ones that it finds in that path
-rpath basically a pool of different path for the same lib so the executable is "smart" enough to look for alternatives if he needs one.
the problem is big for me, no one of this solves my problem and each one of this flags suffer the same problem: ambiguity.
if I just want to link a library that i know there is no way to do this without including a dose of ambiguity in the best case scenario, what i want is:
linking 1 specific library only, and only the 1 that I specify with a precise name and path
avoid auto-completion mechanism like the one on the name given to -l because my libs are named foo.so not libfoo.so
relative path for the linked libs
only consider the explicitly given set of libraries, no other automation of any kind should be involved, no pool of libs, no search-paths, no nothing else, I prefer list of errors instead of an executable linked to a random library
I often deal with different libs in different releases, they often share the same name for historical and compatibility reasons, it's a nightmare compiling and linking with gcc because I never got the one that I want linked to my executable.
Thanks.
The easiest way to do this is to simply specify the library.
gcc -o test test.o /path/my_library.so /path/to_other_library.a
The obvious downside to this approach if of course that if you move that library then your application won't work anymore but since you state that you have the libraries at fixed locations it should work in your case.

RPATH must exist at compile time

Please forgive me if I'm missing something obvious here. I'm developing some applications for another platform, and all of my proprietary libraries are installed to /app/lib. To facilitate this, I specify a runtime library path for each of my binaries as "/app/lib". This works fine; however, it requires that the path "/app/lib" exist in my build environment when linking (even though that directory is empty). I'm using NetBeans, which might be complicating matters, but I can see "-Wl, -rpath /app/lib" being passed to gcc.
I'd like to avoid the need to create an empty "/app/lib" in my build environment, but I don't want to change the file structure on my target platform. If I delete /app/lib from the build environment, I get an error when building that it can't be found. Is there a way to specify a runtime search path without the need for it to exist at link time?
I think the option you are looking for is -Wl,-rpath-link,/path/to/libraries. You need to use both options at once.
The linker will then use -rpath-link to find the libraries at link-time, but it'll encode the -rpath value into the binary for use at run time.
The syntax should be "-Wl,-rpath -Wl,/app/lib" ("-Wl,-rpath,/app/lib" works too). This is a bug in NetBeans. The reason why it's not more critical (and why I didn't notice this before) is that link-time search paths appear to carry over into runtime. Because NetBeans isn't placing a comma between -rpath and /app/lib, /app/lib is being interpreted as a link-time search path. As a result, my dependent libraries are still found at run-time in the appropriate location, but because it's a link-time dependency, the linking fails because /app/lib doesn't exist.

Boost library static linking on Xcode 4

I am using the Boost library on OS X using Xcode. Boost was installed on my system using macports. I have successfully built my app by adding the 3 boost libraries I need (for example, libboost_thread-mt.a) to that Targets 'Link Binary With Libraries' list. However I need to link these libraries statically so that the app will run on other computers without the boost library needing to be installed.
How do I do this exactly? Through my numerous google searches I'm finding I might need to add '-static' - where do I add this in Xcode?
If you've linked with a .a library, then you have already linked statically. You never need to ship .a libraries. They're just bundles of objects.
EDIT: Your error strongly suggests that you're linking the dylib rather than the .a. If you have libfoo.dylib and libfoo.a in your library path, even if you say "link libfoo.a" in Xcode, and even if libfoo.a is earlier in the search path, it will still link libfoo.dylib. This is because Xcode's linking is totally broken and passes -lfoo to the linker (you should never use -l for something you built and have the exact path to). I always recommend linking libraries you built in LDFLAGS in an xcconfig file rather than using the build pane. You pass the exact path you want rather than using -l. See Abandoning the Build Panel for more of my thoughts on xcconfig. It's out of date now, since it was written for Xcode3, but the basics still apply.
Using the build pane, you can also pass the entire path to the library in "Other Linker Flags." But this still has all the problems of the build pane.
The quicker (but less robust) solution is sometimes to add -Wl,-search_paths_first to the "Other Linker Flags." This changes the behavior so that each library path is searched for both .dylib and .a before going on (the default behavior is to search everywhere for .dylib and only then search for .a). So if your .a is in a different directory from your .dylib, and that directory is earlier in the search path, this will work.
This question finally got me to open a radar on this, which I should have done years ago. I recommend that others open duplicates.

Problem with linking in gcc

I am compiling a program in which a header file is defined in multiple places. Contents of each of the header file is different, though the variable names are the same internal members within the structures are different .
Now at the linking time it is picking up from a library file which belongs to a different header not the one which is used during compilation. Due to this I get an error at link time.
Since there are so many libraries with the same name I don't know which library is being picked up. I have lot of oems and other customized libraries which are part of this build.
I checked out the options in gcc which talks about selecting different library files to be included. But no where I am able to see an option which talks about which libraries are being picked up the linker.
If the linker is able to find more than one library file name, then which does the linker pick up is something which I am not able to understand. I don't want to specify any path, rather I want to understand how the linker is resolving the multiple libraries that it is able to locate. I tried putting -v option, but that doesn't list out the path from which the gcc picks up the library.
I am using gcc on linux.
Any help in this regard is highly appreciated.
Regards,
Chitra
Passing -Wl,-t to gcc will tell ld to dump which files it's reading.

Resources