2013年9月3日 星期二

How ot make .a and .so and use it

//refer to http://blog.yam.com/ytha/article/16636287

一般在Linux下用gcc編譯C語言程式, 預設的情況編譯器只會搜尋標準的吸久久(C99)函式庫,
諸如stdio.h, math.h等等, 而標準的Linux系統函式通常存放在/lib 和 /usr/lib,
所以必需要告訴編譯器(linker)搜尋哪個函式庫, 而在Linux下函式庫名稱都是以lib為開頭,
隨後的名稱就根據該函式庫來定(m就代表數學函式庫), 而副檔名.a 就是指靜態函式庫, .so就是共享函式庫。


//test.c
#define PI 3.14159265
int main ()
{
double param, result;
param = 88.0;
result = cos (param*PI/180);
printf ("The cosine of %lf degrees is %lf.\n", param, result );
return 0;
}

使用gcc編譯:
gcc -o test test.c -lm

math.h是C99標準函式庫, 這裡只是舉例, 如果程式加上#include 的話,
這個-lm是可以不用寫的, 但是如果我們今天程式是有關處理系統執行緒的話,
就要加上 -lpthread 來編譯, 因為thread不在吸久久標準函式庫內。

而靜態函式庫是可以獨立存在, 但是不能共用的,常應用於嵌入式系統, 而動態函式庫是不可以獨立存在,
但是可以共用的, 而且一定要放在/lib底下才能實現共用, 所以常運用於PC軟體系統。
一般時後靜態函式比較省記憶體空間, 但是動態函式在需要大量的共用檔案時就比靜態函式庫還要省空間。

靜態函式庫:
比如我們現在在一個名為mytest的目錄中有 a.c, b.c, lib.h, main.c 四個檔案
其內容分別是

//a.c
#include
void a(char * arg)
{
printf("a: you passed %s\n", arg);
}

//b.c
#include
void b(int arg)
{
printf("b: you passed %d\n", arg);
}

//lib.h
void a (char*);
void b (int);

//main.c
#include "lib.h"
int main()
{
a("Hello World");
exit(0);
}
好了, 開始編譯:
# cd mytest
# gcc -c a.c b.c
# ls *.o
您就會見到 a.o 及 b.o 兩個目的檔
再來
# gcc -c main.c 產生main.o的目的檔

現在我們來產生靜態函式庫:
# ar crv libtest.a a.o b.o 產生libtest.a的靜態函式庫

最後來使用這個函式庫來編譯出可執行檔:
# gcc -o main main.o libtest.a 這樣就產生出一個名為 main 的執行檔

我們也可以這樣寫來編出可執行檔
# gcc -o main main.o -L. -ltest
-L. 指目前所在目錄, 如果libtest.a是放在其他目錄下, 請在-L後面加上所在位置
-ltest 就是指 libtest.a

一樣用ldd指令可以查詢執行檔所參考的lib檔喔
# ldd main

如果對windows下面做比較的話:
Linux Windows
目的檔 func.o FUNC.OBJ
靜態函式庫 lib.a LIB.LIB
執行檔 main main.exe


動態函式庫: (我們採用上面的程式資料)
開始來做動態函式庫
# gcc a.c b.c -shared -o libtest.so //編譯a.c及b.c成一個libtest.so動態函式
# gcc -c main.c //產生 main.o目的檔
# gcc -o main main.o libtest.so //利用libtest.so動態函式來產生main可執行檔
# ./main 當你執行main執行檔的時後就出現了錯誤~

而錯誤訊息應該是這樣的:
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
因為要共用喔(前面有說過)所以:
# cp libtest.so /lib //將libtest.so拷備到/lib目錄下

# export LD_LIBRARY_PATH=./
# ./main //再執行一次, 成功了吧~

#gedit /etc/ld.so.conf.d/newapp.conf
add /usr/local/newbuild/lib
#ldconfig -v

一樣用ldd指令可以查詢它的lib檔喔
# ldd main

沒有留言:

張貼留言