90 likes | 184 Views
Static Libraries. inside a static library, you are likely to find that it contains many modules with only one function per module. This gives the linker maximum opportunities to remove unnecessary code .
E N D
Static Libraries • inside a static library, you are likely to find that it contains many modules with only one function per module. • This gives the linker maximum opportunities to remove unnecessary code. • The linker reads the object files contained in the archive one by one when it tries to resolve external symbols. The linker is free to discard any object files that are not required.
Dynamic Libraries • Unlike a static library, which is just an archive of object files, a dynamic library is itself an object file. • Dynamic libraries are created by the linker, unlike static libraries, which are created by the compiler and the ar command. • When you link with a dynamic library, the compiler does not copy any object code into your executable file. • Instead, it records information about the dynamic library in your executable (stub) so that it can be dynamically linked at runtime. • This means that part of the link process is deferred until runtime. • When a dynamically linked program executes, the program performs the final linking stages before it enters main. • When the linker sees a static library, it is free to pull in only the object files that your program actually needs, which keeps the executable as small as possible. • When your code links with a shared object, however, it’s all or nothing. linker cannot discard pieces of the shared object, so yourprocess’s memory will map all the code contained in the shared object, whether itcalls it or not. • 這是為了在有VM時,OS方便管理記憶體映射。若在沒有VM下,使用動態函式庫就可能過於昂貴了!!
Creating a Dynamic Library • hello.c for the main program and empty.c, be an empty shared object. $ cat <<EOF > hello.c #include <stdio.h> int main() { printf("Hello World\n"); } EOF $ cat /dev/null > empty.c Creating shared object $ gcc -shared -fpic -o empty.soempty.c To link hello with this shared object, $ gcc -o hello hello.cempty.so To execute, you need to set LD_LIBRARY_PATH環境變數 $ LD_LIBRARY_PATH=. ./hello Hello World
Example展示靜態與動態鏈結的差異 • we will create a new shared object that does nothing but consume memory. Let’s call it piggy.c: $ cat <<EOF > piggy.c >char bank[0x100000]; >EOF $ • hello.c program that just waits for us to press Ctrl+C so we can examine it while it runs: $ cat <<EOF > hello.c #include <unistd.h> int main(){ pause(); } EOF
靜態鏈結 $ gcc -o hello hello.cpiggy.c $ size hello text data bssdec hex filename 1117 264 1048608 1049989 100585 hello $ nm -S hello | grep bank 080496c0 00100000 B bank • When the modules are linked like this, the memory consumption is visible withthe size command. The nm command shows that the array bank is present and consuming1MB of space.
動態鏈結函式庫 $ gcc -c piggy.c $ arclqlibpig.apiggy.o $ gcc -o hello hello.c -L ./ -lpig $ size hello text data bssdec hex filename 1117 264 4 1385 569 hello $ nm -S hello | grepbank • This time, the size of the executable is noticeably smaller because the bank arrayis not included, which tells us that the piggy.o module was excluded. • The linker isable to determine that there are no references to piggy.o, so it does not link it withthe executable.
查看執行動態鏈結process的memorymap • We’ll run it using the pmapcommandto get a look at the process’s memory map: $ ./hello & $ jobs -x pmap -q %1 7382: ./hello 08048000 4K r-x-- /hello 08049000 4K rw--- /hello b7dab000 4K rw--- [ anon ] b7dac000 1160K r-x-- /libc-2.3.2.so b7ece000 36K rw--- /libc-2.3.2.so b7ed7000 8K rw--- [ anon ] b7ee7000 4K r-x-- /piggy.so b7ee8000 4K rw--- /piggy.so b7ee9000 1032K rw--- [ anon ] //consumed by bank array in virtual address space b7feb000 84K r-x-- /ld-2.3.2.so b8000000 4K rw--- /ld-2.3.2.so bffeb000 84K rw--- [ stack ] ffffe000 4K ----- [ anon ] • So linking with a shared object can force you to consume virtual memory that you otherwise would not use
By default, the compiler uses dynamic linking, which means that if it can choose between a static library and a dynamic library, it will choose the dynamic library. If you want to link exclusively with static objects, you must specify the –static option to gcc/g++.