Introduction
I was looking into if cython could make *.a so that maybe speed can be even faster when calling python. However it ends up with a NOT. The basic reason is that Python Doesn't support static library. Even if you could make *.a from *.o, since cython already made the *.c file for you. So this notes will talk about two things.
Before moving on, first we need to make it clear about what is the processing of converting programming to a code that machine can run. compile -> link -> run Sometimes the compile and link is also called 'build'. ' Before talking about library, first we need to figure out what is link process, because once library is created in compiling process long time ago, it will only be called from linking process. In some cases, the library will be called from run process, which is called dynamically loaded libraries[1]. What's static and how to create a static library To talk about static, the first concept came out of your mind could be: static variable in C. Yes, it is saying the scope of the variable to be accessible is within the file (even though the variable is still lying somewhere in the memory). In contrast, extern is another concept about global variable. So what's the 'static' means in the 'static library' ? Good question. Actually it means 'global', not dynamic. Some where in the memory and not going to be changed. This is the meaning of static in static library. However, the later one usually refers to code/data segment in memory rather than just variables. The C compiler or any other compiler is just translating the language of human readable to computer readable, which is what we call, machine code. Usually there is an output of compiler, usually, it is a obj file. Usually, obj files contains: the definition of functions (code), definition of global variables. If you are not familiar with what a declaration and a definition is, please refer to [1]. To put it simple, the declaration is a promise that a definition of something exists somewhere else in the whole program, including the library you will probably use. Basically, when the compiler saw the source code, it just leave blanks to the referring location where he is not so sure about what to put in the code. Usually, the naming convention for static library is here
So finally let's come to how to build a static library. Use the tool: archiver: ar
The main.c is the code calling the static library, -lx means I searched for a library called libx.a -L. means -Ldir, so the dir is ., so it means searching for current directory. Then run the code ./statically-linked, then the code works. What's shared and how to create a shared library One of the biggest advantage of using a shared library is that, if static library, becomes extremely popular, then the executable in your computer that calling those static library will use a numerous number of useless meaningless disk space just because for static library it just copy the code in *.a to your executable. For this kinds of library, I mean, shared library, the normal linker will behaves a little bit different. When linker saw the reference in the code, it will not include the DEFINITION to the executable. Instead, it just writes down what's the missing variable and which library it should come from IN the executable. So, the acquiring of definition only comes at RUN-TIME. Now, this means that none of the executable has the copy of the *.so's source code. Another thing worthy to know is that if a symbol is pulled from a shared library, then the WHOLE library is mapped into the address space of the program, while for calling static library, only the missing symbol is copied. A useful tool need to be mentioned is the ldd, which can tells you the dependency of current *.so library. Step 1: when compiling the code, using -fPIC flag to force position independent code. so get *.o that is Position independant code, needed for shared libraries. gcc -c -fPIC mean.c -o mean.o Step 2: create the .so library gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 mean.o Step 3: Link dynamic library with the main code gcc main.c -o dynamically_linked -L. -lmean For linking a dynamically library (*.so in unix-like system), you need to add the path to the library into the environment variable because the link stage is executed at the run time. set: LD_LIBRARY_PATH = . However this method is not recommended. See information here [2] Then run the dynamically linked code is fun. Flag explanation: -shared: This is actually an option to the linker, not the compiler. Since gcc contains its own linker. Produce a shared object which can then be linked with other objects to form an executable. -Wl: Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. So here, it is passing -soname libmean.so.1 to the linker, then linker will know the soname of the shared library is libmean.so.1, which would be helpful if there is multiple version of library. So it is saying that he API for libmean.so.1.0.1 is the same as libmean.so.1, which means for all 1.x.x, the API is the same. Then when other code ask to link the libmean.so.1.0.1, it will search for if the soname instead, so they don't have to specifically typing libmean.so.1.0.1 but libmean.so.1 is enough for them to linking the codes. Other voices[3]:
Appendix:
Reference: [1] Beginner's Guide to Linker |
AuthorShaowu Pan Archives
December 2017
Categories
All
|