回覆列表
  • 1 # 使用者7364316064609

    Linux庫有動態與靜態兩種,動態通常用.so為字尾,靜態用.a為字尾。例如:libhello.so libhello.a

    為了在同一系統中使用不同版本的庫,可以在庫檔名後加上版本號為字尾,例如: libhello.so.1.0,由於程式連線預設以.so為檔案字尾名。所以為了使用這些庫,通常使用建立符號連線的方式。

    ln -s libhello.so.1.0 libhello.so.1

    ln -s libhello.so.1 libhello.so

    動態庫和靜態庫的區別:

    當要使用靜態的程式庫時,聯結器會找出程式所需的函式,然後將它們複製到執行檔案,由於這種複製是完整的,所以一旦連線成功,靜態程式庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程式內留下一個標記‘指明當程式執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連線的預設操作是首先連線動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連線。

    兩種庫的編譯產生方法:

    第一步要把原始碼編繹成目的碼。以下面的程式碼hello.c為例,生成hello庫:

    /* hello.c */

    #include

    void sayhello()

    {

    printf("hello,world\n");

    }

    用gcc編繹該檔案,在編繹時可以使用任何全法的編繹引數,例如-g加入除錯程式碼等:

    gcc -c hello.c -o hello.o

    1.連線成靜態庫

    連線成靜態庫使用ar命令,其實ar是archive的意思

    $ar cqs libhello.a hello.o

    2.連線成動態庫

    生成動態庫用gcc來完成,由於可能存在多個版本,因此通常指定版本號:

    $gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

    另外再建立兩個符號連線:

    $ln -s libhello.so.1.0 libhello.so.1

    $ln -s libhello.so.1 libhello.so

    這樣一個libhello的動態連線庫就生成了。最重要的是傳gcc -shared 引數使其生成是動態庫而不是普通執行程式。

    -Wl 表示後面的引數也就是-soname,libhello.so.1直接傳給聯結器ld進行處理。實際上,每一個庫都有一個soname,當聯結器發現它正在查詢的程式庫中有這樣一個名稱,聯結器便會將soname嵌入連結中的二進位制檔案內,而不是它正在執行的實際檔名,在程式執行期間,程式會查詢擁有 soname名字的檔案,%B

  • 中秋節和大豐收的關聯?
  • 為什麼有些人認為洋河藍色經典一直很火?