How to convert Dynamic Executable to Static Executable? - c

How can I convert a pre-built dynamic executable to a static one without recompiling from source? I am using ARMv7 cpu on Linux and I have acess to libraries which are needed by the dynamic executable one . ( I can not use Ermine or Statifier !)

You need the static versions of the libraries you are using, and link them to a compiled version of your program that is prepared for static linking.
So I don't think you can circumvent recompiling.

If you have all the .o files, then you can simply link them with the static versions of the libraries.
This means it's possible to create a static version without compiling from source but usually, people don't keep the .o files so I guess you will have to compile everything from source.

Related

Does everything that may end up in a shared library always need to be compiled with -fPIC?

I'm building a shared library. I need only one function in it to be public.
The shared library is built from a few object files and several static libraries. The linker complains that everything should be build with -fPIC. All the object files and most static libraries were built without this option.
This makes me ask a number of questions:
Do I have to rebuild every object file and every static library I need for this dynamic lib with -fPIC? Is it the only way?
The linker must be able to relocate object files statically, during linking. Correct? Otherwise if object files used hardcoded constant addresses they could overlap with each other. Shouldn't this mean that the linker has all the information necessary to create the global offset table for each object file and everything else needed to create a shared library?
Should I always use -fPIC for everything in the future as a default option, just in case something may be needed by a dynamic library some day?
I'm working on Linux on x86_64 currently, but I'm interested in answers about any platform.
You did not say which platform you use but on Linux it's a requirement to compile object files that go into your library as position independent code (PIC). This includes static libraries at least in practice.
Yes. See load time relocation of shared libraries and position independent code pic in shared libraries.
I only use -fPIC when compiling object files that go into libraries to avoid unecessary overhead.

Compiling with prebuilt static library

I want to use ffmpeg in my android application, considering the size of built library, I decided to write a piece of c code that accomplishes a simple video task.
I have tested my code on my Mac and it compiles and works fine. Now for the NDK part, I can't get it compiled successfully, I have several questions, and hoping for someone to give me a guide.
Can I just cross compile my c code with static ffmpeg library installed on my Mac ? Or if I have to cross compile them before using in my code?
The size of static library is 10Mb, and my c code is only a few lines, how big will be my final shared library ? About 10Mb ?
Any explanation will be appreciated 🙂
Of course, the static lib needs to target the same architecture, so this has to be cross-compiled as well.
It depends on the structure of the static lib. A static lib is normally just an archive of the object (.o) files. So if your library has sufficiently small translation units, and your program uses only a few of them, only these will really be linked to your executable. The outcome might be even smaller if the library and your program are compiled with -ffunction-sections -fdata-sections (which put all functions and all objects of static storage in their own segment) and then you pass -Wl,--gc-sections during linking, so any unused section is discarded. On the other hand, you could run in a situation that you call some functionality of the lib that internally needs close to all other library code, so you end up with nearly the whole library linked into your executable. Therefore: it depends, try it out, and if you're concerned about size, give --gc-sections a try.

Why gcc does not support linking dynamical library into static binary

The background is following: there is 3'rd party provider that provides us with a libveryfancylib.so, in 32b. Softaware that uses the library has quite a load of other linux library dependencies (like QT) also, but they are open source, so no problem for statical linking. The target platform is 64b and running Debian 7.
We can ship the program with binary + dynamical libraries, no problem, but i would rather see single static binary with no dependencies.
So my question is: why i cannot link the dynamical library into static binary? I mean what bit of information is there missing, or is it just feature that is rarely needed -> not implemented.
We can ship the program with binary + dynamical libraries, no problem, but i would rather see single static binary with no dependencies.
What is the problem you are trying to solve?
You can follow the model most commercial applications on Linux do: put your executable, shared libraries and other resources in one directory (possibly with subdirectories). When linking your executable against those shared libraries pass -Wl,-rpath,'$ORIGIN' (in make use -Wl,-rpath,'$$ORIGIN') to the linker, so that when starting your application the runtime linker looks for required shared libraries in the same directory where executable is.
Then archive that directory and give it to your users.
There are programs for MS Windows that can do so, eg DLL to Lib and DLL to Static Lib.
In the open source world, there isn't really much of an incentive to develop such a tool as you can always recompile from source (but of course it's possible that someone somewhere did it anyway).
It's because dynamic libraries and static libraries are two different things. A static library is just an archive of object files (much like a zip archive). A dynamic library is more like an executable program.
So you can't really link anything into a static library, you can only add more object files.

Distribute Libraries Written in C

Suppose I have some code written in C with some data structures defined and some functions to work with those structures and all that is in a directory called src1. Suppose now I want to distribute this code.
If I want to use the external code in src1 in a project what should I do? Should I compile the code in src1 to an .a archive and then include that archive in the other projects I want to use?
Basically what I need to know is the correct conventions to use external code in a project.
Thanks in advance.
To distribute the code in the form of libraries you need follow the below steps:
List down the set of structure, functions, macros etc which you want to expose to other projects.
Group the set of data listed in Point-1 into a set of header files. Rest of your internal stuff can be in other header files.
Compile your code into a static(It will .a for linux based systems or .lib for windows) or dynamic library (It will be a .so/.sl for linux based systems or .dll for windows)
Provide your library and the set of exposed header files (as decided in point-2 above) to the other projects.
Link for creating static or shared libraries using gcc is here
Link for creating static or dynamic libraries in Windows using MSVC is here
Yes, you can use a static library, which is an .a file in Linux, and typically a .lib in Windows. This also requires that you share the header of course, so the code that uses the library can have the proper data structure definitions.
You can use any format (.a or .so) to distribute your library. The first one is static ally Inked and the second one is dynamically linked. To know more see this answer Difference between static and shared libraries?
Which ever you use you always link it in the same way.
gcc -L/path/to/lib -lsrc1 source.c -o source.o
Here, /path/to/lib can contain any of your previously compiled libsrc1.so or libsrc1.a

Can I make gcc ignore static libraries when linking shared libraries?

I've encountered a few cases building projects which use shared libraries or dynamic-loaded modules where the module/library depends on another library, but doesn't check that a shared copy is available before trying to link. This causes object files from a static archive (.a file) to get pulled into the resulting .so, and since these object files are non-PIC, the resulting .so file either has TEXTRELs (very bad load performance and memory usage) or fails altogether (on archs like x86_64 that don't support non-PIC shared libraries).
Is there any way I can make the gcc compiler driver refuse to link static library code into shared library output? It seems difficult and complicated by the possible need to link minimal amounts from libgcc.a and the like...
As you know, you can use -static to only link against static libraries, but there doesn't appear to be a good equivalent to only linking against dynamic libraries.
The following answer may be useful...
How to link using GCC without -l nor hardcoding path for a library that does not follow the libNAME.so naming convention?
You can use -l:[libraryname].so to list the dynamic libraries you want to link against in your library search path. Specifying the .so ending will probably help with your dynamic library only case. You will probably have to specify the whole name with the 'lib' prefix instead of just the shortened version.

Resources