merging object files after compiling executable - linker

i have an executable with many .o files. i would like to reduce these object files to one file but i don't have the source code for the executable. is archiving them using "ar" is the way to do it or is it impossible without recompiling the source?

You can certainly combine the object file with ar into a library. In addition, ld -r allows to combine multiple object files into a single one.

Related

Scons: customize default builders

I have an embedded software entirely written in C and Assembly and for its build process I am using Scons and GCC. The source code is organized in different folders and each folder represents a "standalone" sub-project (i.e., application elf, static libray, etc.).
The main SConstruct file, located inside the main folder of the project, builds a default environment, adding to it some compilation flags shared among all the sub-projects, then it invokes the SConscripts placed in every sub-project, exporting the default environment.
Each sub-project builds a new environment cloning the default one and customize it with new builders, new compilation flags, etc.
The issue comes out because I have to add, for all sub-projects, some actions after each object file's compilation. In short, I need to generate preprocessed file for each ".c" and ".S", invoking the preprocessor with the same flags used by the normal compilation. To do this I think the best solution is to add the compilation flag "-save-temps=obj" to the default environment (this flag tell to the compiler to keep the temporary files), so all sub-projects will inherit this behavior.
The issue is that SCons doesn't track each generated temporary file. Considering that:
for each .c file, gcc will create the two temporary file .i and .s
for each .S file, gcc will create the single temporary file .s
I need to add to the default Object builder:
A SideEffect to tell scons that a .c to .o compilation will create also a .i file;
A SideEffect to tell scons that a .c to .o compilation will create also a .s file;
A SideEffect to tell scons that a .S to .o compilation will create also a .s file;
Is there a way to do this only using the file suffixes and without the enumeration of each target object file?
Furthermore, on each temporary file, I need to invoke a custom tool, again with the same compilation flags used for its compilation, in order to create other files with other debug information. How can I do this? Is there a way to add a post-action to the Object builder?
Thanks,
Ciro

contents of a .a static library file

I was shared a static library file('.a' file). When i opened it with 7z, it included two files, one without extension and one with .o extension. What are these files. Is the .o an object file here and which one of these file is actually linked during linking process.
More info about the .a file:
Lets name the file xyz.a:
When i un compress it or view it with 7z, i can see two files:
- xyz
- abc.o
The '.a' file can contain several '.o' files added by the ar utility. It can also contain an index mapping global symbols to the '.o' files that contain them. On some systems (mostly SysV or GNU based), ar's s option is used to update the index. On other systems (mostly BSD based), the index is updated by a separate ranlib utility.
To answer your questions, the '.o' files are the object (code) files that make up the library, the other file is the index, and some subset of the '.o' files will be linked by the linker, with the assistance of the index to determine which '.o' files are needed.
With the ld linker, the option -l foo would search for a dynamic library called libfoo.so or a static library called libfoo.a. Other ld options control whether it looks for a static or dynamic library and where to look for it.

What are the relationship between LIS, OBJ and EXE files?

I am working with a different compiler CC. It doesn't work like GCC.
When I was using GCC, I can do "gcc -o exe_filename source_filename" and the output would be a exe file.
When I use CC, I need 2 steps. First I compile the source files (suppose it involve a .c and a .h file ) and it create a .lis file and a .obj file. Then I do a link command which created a .exe file.
What is the relationship between LIS, OBJ and EXE files? I ask this because I wonder which files do I need if I want to use the exe in another machine without including unnecessary files. If LIS and OBJ were only used for compilation, I don't need it in another machine.
The compiler takes C files (and includes H files as referenced) and produces object (OBJ) and listing (LIS) files. The object file contains the code and data, but has unresolved external references. The listing typically includes line numbers, error and warning messages, and optional sections such as a type and variable cross-reference.
The linker combines object files and resolves external references to libraries. The result is an executable (EXE) image. (Or shareable image when creating libraries.)
Only the executable file needs to be copied from one system to another to run the application. The listing may be useful for interpreting error messages as it provides the properly correlated line numbers. The object could be useful if the application needs to be relinked due to changes in libraries, particularly if the target system has older versions than the original system.
the OBJ files are the compiled C files in a format that they can be "Linked" together by a linker and turned into an EXE.
Compile -> OBJ -> Link -> EXE
the LIS file is just informational output of the C that the compiler ends up compiling.
All you need once compiled and linked is the EXE
You don't need the other files. The exe will work fine by itself.
I don't have much idea on LIS. But the difference between OBJ and EXE is OBJ file may contain unresolved symbols and in EXE file all symbols are linked and resolved.
If another machine also has same hardware then u can use direct exe to run else you have to cross compile

linking object files and linking static libraries containing these files

Hello Stack Overflow Community,
i am working on a c project to interleave multiple c programs into one binary, which can run the interleaved programs as treads or forks for benchmarking purposes.
Therefore i run make in each program folder of the desired programs and prelink all .o files with "ld -r" to one new .o file. After that i add a specific named function to each of these "big" .o files, which does nothing but run the main() of each program and providing the argc and argv. Then i use objcopy to localize every global Symbol except the unknown ones and the one of my specific function which shall run the main(). At last i link these manipulated .o files together with my program which runs the specific named functions as threads, or forks or after another.
Now to my Question/Problem:
I ran into a problem with static libs. I was using ffmpeg for testing, and it builds static libs such as libavcodc and libavutil and so on. Unfortunately, "ld -r" does not link .a files. So i tried to extract these libs with ar -x and then link the extracted .o files in the way mentioned above to the "big" new .o file. But i did not work because libavcodec and libavutil both include the file ff_inverse.o. That is obviously not a problem when i just build ffmpeg, which will link these static libraries. But still, both libraries include it, so there must be a machanism which makes the choice, which ff_inverse.o to use and to link. So my Question: How does this work? Where is the difference?
The way ld does it with normal linking is to prioritize the libraries. Libraries listed first in the command line are linked in first, and only if symbols still are unresolved does it move on to the next library. When linking static libraries, it ignores the name of each .o file, because the name is unnecessary, only the exported symbols are necessary. You may want to emulate that behavior, by extracting libraries in a sorted order.

What exactly does "ar" utility do?

I don't really understand what ar utility does on Unix systems.
I know it can be somehow used for creating c libraries, but all that man page tells me is that it is used to make archives from files, which sounds similar to, for example, tar....
The primary purpose is to take individual object files (*.o) and bundle them together into a static library file (*.a). The .a file contains an index that allows the linker to quickly locate symbols in the library.
Tar doesn't create files that linkers understand.
ar is a general purpose archiver, just like tar. It just "happens" to be used mostly for creating static library archives, one of its traditional uses, but you can still use it for general purpose archiving, though tar would probably be a better choice. ar is also used for Debian .deb packages.
Exactly, ar is an archiver. It simply takes a set of object files (*.o) and put them in an archive that you call a static library.
It takes code in the form of object files (.obj, .o, etc) and makes a static library (archive). The library can then be included when linking with ld to include the object code into your executable.
Take a look at the example usage in the Wikipedia article.
You might want to run man ar to get the full picture. Here's a copy of that on the web.
To quote:
The GNU ar program creates, modifies, and extracts from archives. An
archive is a single file holding a collection of other files in a
structure that makes it possible to retrieve the original individual
files (called members of the archive).
ar is considered a binary utility because archives of this sort are
most often used as libraries holding commonly needed subroutines.
ar is specifically for archives (or libraries) of object code; tar is for archives of arbitrary files. Anybody's guess why GNU refers to these as 'archives', in other environments this utility is called the 'librarian', and the resulting files just libraries.

Resources