8種機械鍵盤軸體對比
本人程序員,要買一個寫代碼的鍵盤,請問紅軸和茶軸怎么選?
This article mainly introduces the statics library and shared library on Linux and has done some experiments for better comprehension.
Static library,又稱為歸檔文檔(archive). 在Linux系統中一般以.a作為后綴名.用以聲明除了C語言標準庫之外的庫文檔的目錄. 這個聲明是靜態的,也就是說,當許多應用進程同時運行并且都是用來自同一個函數庫的函數時,在內存中就會存有這個函數的多份拷貝.這將大量消耗內存和磁盤空間. 類似與Windows中的靜態鏈接庫.lib文檔
共享庫(shared library / dynamic library)
共享庫克服了靜態庫的不足,典型的后綴名是.so。類似與Windows下的dll文檔。
In Arch Linux, the paths of shared library files are declared in /etc/ld.so.conf. You can add your specified path into this file and then using sudo ldconfig for generating their so-name files if there is update of these library files happening.
The naming suggestion of Linux shared library
Every shared library has its filename and so-name(Short for shared Object name, 簡單共享名). The following naming rules are commonly obeyed:
filename: libname.so.x.y.z
so-name: libname.so.x
x 代表了主版本號,主版本號之間不同通常是無法相互兼容的。
y 代表次版本號,可以向下兼容。
z 代表發布版本號,之間可以相互兼容。
當運行 ldconfig 命令后,系統會為制定目錄下面的動態庫文檔新建與 so-name 同名的軟鏈接。當編譯完進程需要鏈接的時候,查找的就是這些對應的 so-name。可以用環境變量 LD_LIBRARY_PATH 指定so-name files所在的目錄。
First experiment
Supposing that we want to create a shared library for calling function hello declared by hello.h, we start by writing our code here:
1
2
3
4
5
6
7void (const char* name)
{
printf("hello %s!n", name);
}1
2void (const char* name);
Then we compile it by gcc to generate shared lib:
1gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.1
Let me explain every option of the above command. -fPIC means generating position independent code, i.e., address jumping is relative rather than absolute. This option is required in generating library file because lib file usually locates at some place and is called by programs from other places, or the program is generated at some place but is moved to other path. -shared -o indicates a shared library file .so.x.y.z. And -Wl,-soname,libhello.so.0 specifies its so-name as ‘libhello.so.0’.
Now we check our files and should see a new file like this picture:
Next we update by ldconfig
1ldconfig -n shared-library/
Note that -n specifies the dir only being processed(Because we only created one lib file under shared-library, it has no need to update all). If you have added the path into /etc/ld.so.conf, you can also simply run sudo ldconfig and see the same change:
As we can see, the so-name symbolic link has been created. Now we can test this new lib by writing a test code:
1
2
3
4
5
6
7
8int main()
{
hello("handy");
return 0;
}
Then we create a symbolic link to the so-name file in order for gcc compiler specification:
Now we make these three stages of shared library prepared(.so, .so.x and .so.x.y.z), then we compile and link, with relevent paths specified:
1gcc main.c -I /home/shane/Experiments/shared-library/ -L. -lhello -o main
where -I specifies the path of hello.h, -L for the path of libhello.so.
Since we have specified the path of so-name to gcc compiler but have not done that for Linux executer(one of the features of shared library), an error of failing to find the so-name file appears when running the program. So we use LD_LIBRARY_PATH to set it and run again:
1export LD_LIBRARY_PATH="$HOME/Experiments/shared-library/"
More exploration
用ldd查看其依賴的動態庫:
我們發現main進程依賴的動態庫名字是libhello.so.0,既不是libhello.so也不是libhello.so.0.0.1。其實在生成main進程的過程有如下幾步:鏈接器通過編譯命令-L. -lhello在當前目錄查找libhello.so文檔
讀取libhello.so鏈接指向的實際文檔,這里是libhello.so.0.0.1
讀取libhello.so.0.0.1中的SONAME,這里是libhello.so.0
將libhello.so.0記錄到main進程的二進制數據里
所以你看,進程并不知道 so-name file 在哪里,我們當然要在運行進程前 specify 一波了。
Second experiment
Now we emulate the situation of updating lib files. Suppose that we modify our code:
1
2
3
4
5
6
7# include
void hello(const char* name)
{
printf("hello %s, welcome to the world!n", name);
}
Since the change is trivial, we keep the so-name when compiling:
1gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.2
Now there are two versions exist, we update by ldconfig and see the change:
The so-name file link to the new version of lib file. And we run the program and see the immediate change:
So you see, this is the significance or the essence of so-name mechanism. We don’t have to re-link the program after modifying the shared library code.
Summary
In practical production, the compilation and execution are usually departed. Generally:specify the so-name when generating shared lib files
Ensure the availability of libXXX.so file by -L and -l when linking executable program
Ensure the existence of shared lib file and use LD_LIBRARY_PATH to specify the directory of its so-name link when running program
References