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.
Related
in what usage circumstance use "-c" option in gcc to only compile source files to object files but not link them? Could anybody share some usage scenarios?
One example is when you're linking against external, pre-compiled libraries, eg:
$ gcc -c myfile.c
$ gcc myfile.o precompiled_object.o -lprecompiled_lib
The two steps can happen in different parts of a build pipeline, or in different pipelines / components (e.g. myfile.o may be re-used to produce different products, which is actually another use case).
Another example is when you're not the one doing the linking e.g. you supply object files and a third party is doing the linking.
Another example is when you only want to check your code (the current file) compiles, instead of (re-) building the entire project, which may take long.
I am doing a project that includes writing a makefile. Here I have 2 different makefiles. The first one does the initial build step. In the second makefile I am trying to use the initially generated object files (paths provided) and add one more additional object file generated else where. The problem I am facing here is that the linker is unable to link this new object file to the older ones.
I am using this command to do this step.
arm-none-eabi-g++ -T ../linker.ld -nostartfiles -Xlinker --gc-sections -Wl,-Map,"map_file.map" -specs=nano.specs -o "target.elf" new_file.o all_older_files.o
Here the new_file.o is of arm_eabi version 0 and all_older_files.o is arm_eabi version 5. However, this is not giving me any error or warning. And, interesting thing is that, some of the symbols in the new_file.o are being included in the target.elf file. I have checked and checked the linker script but unable to find a solution and also, check if the eabi version is making some difference, but it is the same if I manually edit the elf file using an elf editor.
All I want is that I need to include the sections in the new_file.o in this target.elf so that I can make use of these.
I think I got this. Thank you #Notlikethat, your insight helped me. I figured out that the "--gc-sections" is ignoring the symbols and sections that weren't referenced.
However, when I tried this the first time, the sections were off by large memory portions than it should be and thought this wasn't the solution. But, later I have noticed that the initial auto-gen makefile is also doing the same removing unused sections. So I had to disable that in eclipse project setting and then remove this flag in my makefile as well. This placed the sections where it should be.
Thank you so much, this has saved me tons of time as I was fighting with this for a little longer than needed.
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).
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.
Why is it that some static libraries (lib*.a) can be linked in the same way that shared libraries (lib*.so) are linked (ld -l switch), but some can not?
I had always been taught that all libraries, static or not, can be linked with -l..., however I've run into one library so far (GLFW), which does nothing but spew "undefined reference" link errors if I attempt to link it this way.
According to the response on this question, the "proper" way to link static libraries is to include them directly, along with my own object files, rather than using -l. And, in the case of the GLFW library, this certainly solves the issue. But every other static library I'm using works just fine when linked with -l.
So:
What could cause this one library to not work when linked rather than included directly? If I knew the cause, maybe I could edit and recompile the library to fix the issue.
Is it true that you're not supposed to link static libraries the same way you link shared libraries? (And if not, why not?)
Is the linker still able to eliminate unused library functions from the output executable when the library is directly included in this way?
Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!
Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.
-L[path] -l[lib]
The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it's not then you can add the directory to the list using -L or name the file by name, as you say.
The same is true for shared libraries, actually, although they're more likely to be found, perhaps.
The reason is historical. The "ar" tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by "tar" for that purpose. It stores files (object files, in this case) in a package. And there's a separate extension containing the symbol table for the linker to use. It's possible if you are manually managing files in the archive that the symbol table can get out of date.
The short answer is that you can use the "ranlib" tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.