日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > 使用Automake 創(chuàng)建和使用靜態(tài)庫/動態(tài)庫

          使用Automake 創(chuàng)建和使用靜態(tài)庫/動態(tài)庫

          發(fā)布人:電子禪石 時間:2019-09-05 來源:工程師 發(fā)布文章

          使用Automake 創(chuàng)建和使用靜態(tài)庫/動態(tài)庫

          1. 目錄結(jié)構(gòu)如下:
          example
          |——src 目錄(存放源代碼文件)
                  |——hello.c
          |——lib 目錄(存放用來生成庫的文件)
                  |——test.c 用來生成靜態(tài)庫libhello.a
          |——include 目錄(存放程序中使用的頭文件)
                  |——hello.h
          2. 編寫的各個目錄下的源文件
          hello.h 文件
          extern void print(char *);
          test.c 文件
          #include<stdio.h>
          void print(char *msg)
          {
          print(“%s\n”, msg);
          }
          hello.c 文件
          #include “hello.h”
          int main()
          {
          print(“Hello static library!”);//這里用到的是靜態(tài)庫中的函數(shù)
          return 0;
          }
          3. 編寫lib/Makefile.am 文件
          noinst_LIBRARIES=libhello.a
          libhello_a_SOURCES=test.c
          AUTOMAKE_OPTIONS=foreign
          第一行noinst 表示生成的是靜態(tài)庫,不需要make install ,直接制定它的位置和名字就
          可以使用。
          第二行表示用來生成靜態(tài)庫的源文件。如果要把靜態(tài)庫生成到其他地方,可以在=后面
          加上路徑(建議用絕對路徑,并將所要用到的靜態(tài)庫生成在同一個文件夾下,如lib)。
          第三行AUTOMAKE_OPTIONS 是Automake 的選項。Automake 主要是幫助開發(fā) GNU 軟
          件的人員來維護軟件,所以在執(zhí)行Automake 時,會檢查目錄下是否存在標(biāo)準(zhǔn) GNU 軟件中
          應(yīng)具備的文件,例如 'NEWS'、'AUTHOR'、 'ChangeLog' 等文件。設(shè)置為foreign 時,Automake
          會改用一般軟件的標(biāo)準(zhǔn)來檢查。如果不加這句的話,需要在autoconf之前,先執(zhí)行touch NEWS
          README AUTHORS ChangeLog 來生成'NEWS'、'AUTHOR'、 'ChangeLog' 等文件
          4. 編寫src/Makefile.am 文件
          AUTOMAKE_OPTIONS=foreign
          INCLUDES= -I../include
          bin_PROGRAMS=hello
          hello_SOURCES=hello.c
          hello_LDADD=../lib/libhello.a
          第二行指定頭文件的位置,-I 是idirafter 的縮寫。../include 指定頭文件的位置,..是上
          一級目錄,也就是這里的example 目錄。
          第三行指定生成可執(zhí)行文件名hello,在這里可執(zhí)行文件生成在src 下,建議將可執(zhí)行文
          件生成到一個特定的文件夾下,讓它和源代碼分開,如/root/test 目錄下。寫法為:
          bin_PROGRAMS=/root/test/hello,后面的第四、五行也相對應(yīng)地變?yōu)椋?br />_root_test_hello_SOURCES=hello.c
          _root_test_hello_LDADD=../lib/libhello.a
          第四行指定生成可執(zhí)行文件hello 的源代碼文件,如果hello.c 在其他目錄下,需要加上
          完整的路徑。
          第五行指定需要使用靜態(tài)庫的位置。
          5. 生成靜態(tài)庫文件lib/libhello.a。
          執(zhí)行autoscan 生成configure.scan 文件,將它重命名為configure.in 并修改其內(nèi)容。
          #configure.in
          # Process this file with autoconf to produce a configure script.
          AC_PREREQ(2.59)
          AC_INIT(libhello.a,1.1,[])
          AM_INIT_AUTOMAKE
          # Checks for programs.
          AC_PROG_CC
          # Checks for libraries.
          AC_PROG_RANLIB//需要加入的內(nèi)容,因為使用了靜態(tài)庫
          # Checks for header files.
          # Checks for typedefs, structures, and compiler characteristics.
          # Checks for library functions.
          AC_OUTPUT([Makefile])
          AC_INIT(FILE)
          該宏用來檢查源代碼所在路徑,autoscan 會自動產(chǎn)生,一般無須修改它。
          AM_INIT_AUTOMAKE(PACKAGE,VERSION)
          這個是使用 Automake 所必備的宏,PACKAGE 是所要產(chǎn)生軟件的名稱,VERSION 是版
          本編號。也可以把包和版本號等信息放在AC_INIT(FILE) 宏里。
          AC_PROG_CC
          檢查系統(tǒng)可用的C 編譯器,若源代碼是用C 寫的就需要這個宏。
          AC_OUTPUT(FILE)
          設(shè)置 configure 所要產(chǎn)生的文件,若是Makefile ,configure 便會把它檢查出來的結(jié)果
          填充到Makefile.in 文件后產(chǎn)生合適的 Makefile。 后面的FILE 是一個Makefile 的輸出列表,
          你可以選著將要輸出的Makefile 的位置和個數(shù)。建議只在src 中輸出Makefile。
          在lib 目錄下依次執(zhí)行 aclocal 、autoconf、automake --add-missing、./configure、make,
          此時在該目錄下就可以看到生成的靜態(tài)庫文件libhello.a
          6. 在src 目錄下,執(zhí)行autoscan 生成configure.scan 文件,將它重命名為configure.in 并修
          改其內(nèi)容。
          #configure.in
          # Process this file with autoconf to produce a configure script.
          AC_PREREQ(2.59)
          AC_INIT(hello,1.1,[])
          AM_INIT_AUTOMAKE
          AC_CONFIG_SRCDIR([hello.c])
          # Checks for programs.
          AC_PROG_CC
          # Checks for libraries.
          # Checks for header files.
          # Checks for typedefs, structures, and compiler characteristics.
          # Checks for library functions.
          AC_OUTPUT([Makefile])
          7. 在src 目錄下依次執(zhí)行 aclocal 、autoconf、automake --add-missing、./configure、make,
          生成可執(zhí)行文件hello
          8. 執(zhí)行make install 進行安裝,最后輸入hello 來運行程序,查看效果:
          Hello static library!
          執(zhí)行成功!
          使用gcc 創(chuàng)建和使用靜態(tài)庫
          1. 編寫mylib.h 文件
          #ifndef _mylib_h_
          #define _mylib_h_
          void welcome();
          void outstring(const char * str);
          #endif
          2. 編寫mylib.c 文件,用來生成靜態(tài)庫。
          #include <stdio.h>
          void welcome()
          {
          printf(“welcome to libmylib\n”);
          }
          void outstring(const char * str)
          {
          if(str!=NULL)
          printf(“%s”,str);
          }
          3. 編譯源文件,產(chǎn)生目標(biāo)代碼
          gcc –o mylib.o –c mylib.c
          4. 將上面產(chǎn)生的目標(biāo)文件加入到靜態(tài)庫中,并把靜態(tài)庫拷貝到系統(tǒng)默認的路徑
          ar rcs libmylib.a mylib.o
          cp libmylib.a /usr/lib/
          5. 編寫測試程序來使用剛才創(chuàng)建的靜態(tài)庫 libmylib.a
          #include “mylib.h”
          #include <stdio.h>
          Int main()
          {
          printf(“create and use library:\n”);
          welcome();
          outstring(“It’s a successful\n”);
          }
          6. 編譯使用庫函數(shù)的程序
          gcc –o test test.c -lmylib
          運行./test 查看結(jié)果。


          使用Automake 創(chuàng)建和使用動態(tài)庫


          動態(tài)庫與靜態(tài)庫的差別在于:動態(tài)庫是在程序執(zhí)行的時候加載到內(nèi)存,供調(diào)用函數(shù)使用。
          1. 目錄結(jié)構(gòu)如下:
          example
          |——src 目錄(存放源代碼文件)
          |——hello.c
          |——lib 目錄(存放用來生成庫的文件)
          |——test.c 用來生成動態(tài)庫libhello.la
          |——include 目錄(存放程序中使用的頭文件)
          |——hello.h
          2. 編寫各個目錄下的源文件如下:
          hello.h 文件
          extern void print(char *);
          test.c 文件
          #include<stdio.h>
          void print(char *msg)
          {
          print(“%s\n”, msg);
          }
          hello.c 文件
          #include “hello.h”
          int main()
          {
          print(“Hello static library!”);//這里用到的是動態(tài)庫中的函數(shù)
          return 0;
          }
          3. 在lib 目錄下編譯需要生成動態(tài)庫的文件,生成動態(tài)庫,并安裝到系統(tǒng)的標(biāo)準(zhǔn)庫中,供
          程序調(diào)用。具體步驟如下:
          (1) 編寫Makefile.am 文件
          AUTOMAKE_OPTIONS=foreign
          lib_LTLIBRARIES=libhello.la
          libhello_la_SOURCES=test.c
          這里lib_LTLIBRARIES 的意思是生成的動態(tài)庫,然后指定動態(tài)庫依賴的源文件
          test.c ,若有多個源文件用空格隔開。
          (2) 在lib 目錄下,用命令autoscan 產(chǎn)生configure.scan 文件,并改名為configure.in。 這
          里需加上宏AC_PROG_LIBTOOL,表示利用libtool 來自動生成動態(tài)庫
          #configure.in
          # Process this file with autoconf to produce a configure script.
          AC_PREREQ(2.59)
          AC_INIT(hello,1.0, [miaoquan@nou.com.cn])
          AM_INIT_AUTOMAKE
          AC_CONFIG_SRCDIR([test.c])
          #AC_CONFIG_HEADER([config.h])
          # Checks for programs.
          AC_PROG_CC
          # Checks for header files.
          # Checks for typedefs, structures, and compiler characteristics.
          # Checks for library functions.
          AC_PROG_LIBTOOL
          AC_CONFIG_FILES([Makefile])
          AC_OUTPUT
          (3) 執(zhí)行命令aclocal、libtoolize -f -c 、autoconf、automake --add-missing、./configure、
          make、make install 將動態(tài)庫安裝到系統(tǒng)的標(biāo)準(zhǔn)庫中,以供調(diào)用(一般為/usr/local/lib)。
          注:libtoolize 提供了一種標(biāo)準(zhǔn)的方式來將libtool 支持加入一個軟件包,而GNU libtool 是
          一個通用庫支持腳本,將使用動態(tài)庫的復(fù)雜性隱藏在統(tǒng)一、可移植的接口中。
          4. 生成src 目錄下的hello 可執(zhí)行文件
          (1) 編寫src/Makefile.am 文件
          AUTOMAKE_OPTIONS=foreign
          INCLUDES= -I../include
          bin_PROGRAMS=hello
          hello_SOURCES=hello.c
          hello_LDADD=-lhello
          -ldir 指定編譯時搜索庫的路徑。與靜態(tài)庫不同的是,創(chuàng)建動態(tài)庫時不用指定庫路
          徑,編譯器自動在標(biāo)準(zhǔn)庫中查找libhello.so 文件。
          (2) 執(zhí)行autoscan 生成configure.scan 文件,將它重命名為configure.in 并修改其內(nèi)容。
          # configure.in
          # Process this file with autoconf to produce a configure script.
          AC_PREREQ(2.59)
          AC_INIT(hello,1.0, [miaoquan@nou.com.cn])
          AM_INIT_AUTOMAKE
          AC_CONFIG_SRCDIR([hello.c])
          #AC_CONFIG_HEADER([config.h])
          # Checks for programs.
          AC_PROG_CC
          # Checks for header files.
          # Checks for typedefs, structures, and compiler characteristics.
          # Checks for library functions.
          AC_CONFIG_FILES([Makefile])
          AC_OUTPUT
          (3) 在src 目錄下編譯并生成目標(biāo)文件,執(zhí)行命令aclocal、libtoolize -f -c 、autoconf、
          automake --add-missing、./configure、make,此時你一定會覺得,成功近在咫尺了。再
          執(zhí)行目標(biāo)文件./hello,結(jié)果卻在你的意料之外:
          ./hello: error while loading shared libraries: libhello.so.0 : cannot open shared object file:
          No such file or directory
          在執(zhí)行目標(biāo)文件的時候,Shell 找不到共享庫的位置,需要我們手工載入庫路徑。
          5. shell 搜索動態(tài)庫路徑位置的兩種方法
          (1) 使用命令導(dǎo)入動態(tài)庫的路徑,命令如下:
          export LD_LIBRARY_PATH=dir (如/usr/local/lib)
          (2) 修改/etc/ld.so.conf 文件,加入搜索路徑,修改后用ldconfig 命令載入修改。
          將自己可能存放庫文件的路徑都加入到/etc/ld.so.conf 中是明智的選擇 ^_^。添加
          方法也極其簡單,將庫文件的絕對路徑直接寫進去就OK 了,一行一個。例如:
          /usr/local/lib
          /usr/lib
          /lib
          需要注意的是:這種搜索路徑的設(shè)置方式對于程序連接時的庫(包括共享庫和靜態(tài)
          庫)的定位已經(jīng)足夠了,但是對于使用了共享庫的程序的執(zhí)行還是不夠的。這是 因為
          為了加快程序執(zhí)行時對共享庫的定位速度,避免使用搜索路徑查找共享庫的低效率,所
          以是直接讀取庫列表文件 /etc/ld.so.cache 從中進行搜索的。/etc/ld.so.cache 是一個非
          文本的數(shù)據(jù)文件,不能直接編輯,它是根據(jù) /etc/ld.so.conf 中設(shè)置的搜索路徑由
          /sbin/ldconfig 命令將這些搜索路徑下的共享庫文件集中在一起而生成的(ldconfig 命令
          要以 root 權(quán)限執(zhí)行)。因此,為了保證程序執(zhí)行時對庫的定位,在 /etc/ld.so.conf 中
          進行了庫搜索路徑的設(shè)置之后,還必須要運行 /sbin/ldconfig 命令更新 /etc/ld.so.cache
          文件之后才可以。ldconfig ,簡單的說,它的作用就是將/etc/ld.so.conf 列出的路徑下的庫
          文件 緩存到/etc/ld.so.cache 以供使用。因此當(dāng)安裝完一些庫文件,(例如剛安裝好glib),
          或者修改ld.so.conf 增加新的庫路徑后,需要運行一下/sbin/ldconfig 使所有的庫文件都
          被緩存到ld.so.cache 中,如果沒做,即使庫文件明明就在/usr/lib 下的,也是不會被使
          用的,結(jié)果編譯過程中報錯,缺少xxx 庫,去查看發(fā)現(xiàn)明明就在那放著,搞的想大罵
          computer 蠢豬一個^_^。極力推薦使用這種方法!
          利用gcc 創(chuàng)建和使用動態(tài)庫
          1. 用下面的命令將mylib.c 程序創(chuàng)建成一個動態(tài)庫:
          gcc –fPIC –o mylib.o –c mylib.c
          gcc –shared –o libtt.so mylib.o
          -fPIC 作用于編譯階段,告訴編譯器產(chǎn)生與位置無關(guān)代碼(Position-Independent Code),
          則產(chǎn)生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內(nèi)存的
          任意位置,都可以正確的執(zhí)行。這正是共享庫所要求的,共享庫被加載時,在內(nèi)存的位置不
          是固定的。
          -shared 作用于鏈接階段,實際傳遞給鏈接器ld,讓其添加作為共享庫所需要的額外描
          述信息,去除共享庫所不需的信息。
          也可以直接使用下面一條命令:
          gcc –fPIC –shared –o libtt.so mylib.c
          2. 將動態(tài)庫拷貝到linux 的標(biāo)準(zhǔn)庫中,usr/local/lib 或者/usr/lib 或者/lib:
          cp libttt.so /usr/local/lib
          3. 編譯src 目錄下的源程序時,指定動態(tài)庫文件的目錄,調(diào)用動態(tài)庫中的函數(shù)
          gcc –o test test.c /usr/lib/libttt.so
          4. 設(shè)置shell 動態(tài)庫搜索路徑,運行生成的可執(zhí)行文件。
          ---------------------------------------------------------------------------

          AUTOMAKE_OPTIONS=foreign

          INCLUDES=-I$(top_srcdir)/libpr/include -I$(top_srcdir)/vt/include

          noinst_PROGRAMS =libvt.so
          libvt_so_SOURCES=vty/vtcmd.c  vty/vtdrv.c vty/vty.c vty/evtd.c telnet/telcmd.c telnet/teldrv.c  telnet/telnegot.c telnet/telsvr.c telnet/telsess.c vty/defcmd.c  vty/vtobj.c
          libvt_so_LDFLAGS = -fPIC -shared
          libvt_so_LDADD=$(top_srcdir)/libpr/libpr.a

          bin_PROGRAMS = test_telnetd
          test_telnetd_SOURCES = test/test_telnetd.c 
          test_telnetd_LDADD=$(top_srcdir)/libpr/libpr.a libvt.so

          上面這段代碼是從我的一個工程的Makefile.am中摘抄過來的,使用不少技巧。

          1、動態(tài)庫實際上也是ELF格式,所以我們使用PROGRAMS宏,automake將他按執(zhí)行文件規(guī)格設(shè)置環(huán)境,如果使用noinstall_LIBRARIES那么就變成*.a靜態(tài)庫了。

          2、因為是動態(tài)庫,所以我們有必要加入-fPIC -shared

          3、test_telnetd需要調(diào)用libvt.so,所以他們之間存在依賴關(guān)系。我們將libvt.so直接添加在LDADD 中,automake會自動他們建立依賴關(guān)系,在Makefile中可以到test_telnetd_DEPENDENCIES,里面包含 libvt.so。

          這里有幾個要緊需要注意:

          1、$(bin_PROGRAMS)編譯順序在$(noinstall_PROGRAMS)之前,因為test_telnetd需要libvt.so,所以會找不到libvt.so。

          2、在LDADD中如果使用-lvt不會建立依賴關(guān)系,如果使用$(top_srcdir)/vt/libvt.so也不行。

          3、實際上如果不行的話,我們可以直接使用test_telnetd_DEPENDENCIES來指定libvt.so

          4、如果需要make install 安裝libvt.so到lib,那么使用XXX_PROGRAMS=...的方法,然后指定XXXbin=...就行了。類似于bin_PROGRAMS。

          這里使用到的技巧都很有用,值得記錄下來。

          *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



          關(guān)鍵詞: makefile

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉