系統程式員成長計劃-工程管理(三)

來源:互聯網
上載者:User

轉載時請註明出處和作者連絡方式

文章出處:http://www.limodev.cn/blog
作者連絡方式:李先靜 <xianjimli@gmail.com>

 

系統程式員成長計劃-工程管理(三)

函數庫

現在我們用automake來管理我們前面所建立的函數庫,這是一個基礎的函數庫,我們就把它命名為base吧。

o 目錄結構
base 根目錄
base/src 原始碼目錄

o 建立Makefile模板
base/Makefile.am內容為:
SUBDIRS=src

base/src/Makefile.am內容為:

lib_LTLIBRARIES=libbase.lalibbase_la_SOURCES= darray.c /    darray.h /    dlist.c /    dlist.h /    darray_iterator.h /    dlist_iterator.h /    hash_table.c /    hash_table.h /    invert.c /    iterator.h /    linear_container_darray.c /    linear_container_darray.h /    linear_container_dlist.c /    linear_container_dlist.h /    linear_container.h /    queue.c /    queue.h /    sort.c /    sort.h /    stack.c /    stack.h /    typedef.hlibbase_la_LDFLAGS=-lpthreadnoinst_PROGRAMS=darray_test dlist_testdarray_test_SOURCES=darray.cdarray_test_CFLAGS=-DDARRAY_TESTdlist_test_SOURCES=dlist.cdlist_test_CFLAGS=-DDLIST_TESTbasedir=$(includedir)/basebase_HEADERS=darray.h dlist.h iterator.h linear_container_dlist.h typedef.h /    darray_iterator.h  dlist_iterator.h  linear_container_darray.h  /    linear_container.hEXTRA_DIST=/    linear_container_test.c /    invert_ng.c /    darray_iterator.c /    dlist_iterator.c /    test_helper.c

LTLIBRARIES是關鍵字。LT代表libtool,libtool是用來封裝共用庫在不同平台上差異的指令碼,其具體實現我們不用關心。

libbase.la 是函數庫的名稱,副檔名用.la而不是.so或.a,同時會產生共用庫和靜態庫。libbase_la_SOURCES是產生libbase.la所需要 的源檔案。
LDFLAGS是關鍵字,用來指定連結時需要的參數,-lpthread表示要連結libpthread.so。

noinst_PROGRAMS是關鍵字,表示不需要安裝的可執行檔,通常是測試程式。為了簡單明了,這裡沒有寫出全部的測試程式。

CFLAGS是關鍵字,用來指定編譯和預先處理時的參數。

HEADERS是關鍵字,列出所要安裝的標頭檔。xxx_HEADERS和xxxdir要配套使用,後者表示要安裝的位置。這裡在 base_HEADERS中列出的標頭檔會安裝到basedir目錄裡。

o 建立autoconf的模板。
運行:
autoscan
mv configure.scan configure.in

然後按前面介紹的方法修改configure.in,得到下面的內容:

AC_PREREQ(2.61)AC_INIT(base, 0.1, xianjimli@hotmail.com)AC_CONFIG_SRCDIR([src/invert.c])AC_CONFIG_HEADER([config.h])AM_INIT_AUTOMAKE(base, 0.1)# Checks for programs.AC_PROG_CCAC_PROG_LIBTOOL # Checks for libraries.# FIXME: Replace `main' with a function in `-lpthread':AC_CHECK_LIB([pthread], [main]) # Checks for header files.AC_HEADER_STDCAC_CHECK_HEADERS([stdlib.h string.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics.AC_C_INLINEAC_TYPE_SIZE_T # Checks for library functions.AC_FUNC_MALLOCAC_FUNC_REALLOC AC_CONFIG_FILES([Makefile                 src/Makefile])AC_OUTPUT

與前面不同的是:
AC_PROG_LIBTOOL 用來檢查libtool指令碼。
AC_CHECK_LIB用來檢查共用庫是否存在。
AC_CHECK_HEADERS 用來檢查標頭檔是否存在。
AC_FUNC_MALLOC 用來檢查標準的malloc函數是否存在。

o 收集用到的m4宏。
運行:aclocal

o 產生配置標頭檔的模板。
運行:autoheader

o 建立README、NEWS、ChangeLog和AUTHORS幾個檔案。

o 產生libtool需要的檔案。
運行:libtoolize –force –copy

這個命令的主要功能是產生ltmain.sh,而ltmain.sh用來產生libtool指令碼。

o 產生Makefile.in和需要的指令碼。
運行:automake -a

o 產生configure指令碼。
運行:autoconf

o 產生最終的Makefile。
運行:./configure –prefix=$HOME/usr

o 編譯運行:make

o 安裝
運行:make install

o 發布軟體包
運行:make dist

我們編譯好的檔案安裝到/home/lixianjing/usr/lib/目錄下了:
libbase.a libbase.la libbase.so libbase.so.0 libbase.so.0.0.0

靜態庫:libbase.a
動態庫:libbase.so
libtool的封裝:libbase.la

標頭檔和庫都安裝好了,調用者還需要知道下列資訊才能使用:

標頭檔和庫安裝在哪裡?
還依賴哪些其它模組?

為瞭解決這個問題,我們需要藉助另外一個名為pkg-config的工具。pkg是package的簡寫,pkg-config負責查詢指定軟體包 的配置資訊,如軟體包的名稱、說明、版本號碼、標頭檔、庫和依賴關係等等。為了讓pkg-config能正常工作,軟體包的實現者需要提供一個副檔名為pc 的設定檔。

系統中的pkg-config設定檔通常放在/usr/lib/pkgconfig/和/usr/local/lib/pkgconfig/下, 下面是gtk+-2.0.pc:

prefix=/usrexec_prefix=/usrlibdir=/usr/libincludedir=/usr/includetarget=x11 gtk_binary_version=2.10.0gtk_host=i386-redhat-linux-gnu Name: GTK+Description: GIMP Tool Kit (${target} target)Version: 2.12.10Requires: gdk-${target}-2.0 atk cairoLibs: -L${libdir} -lgtk-${target}-2.0Cflags: -I${includedir}/gtk-2.0

前面部分是定義的一些變數,後面是一些關鍵字:

Name: 名稱
Description: 功能描述
Version: 版本號碼
Requires: 所依賴的軟體包
Libs: 調用者的連結參數。
Cflags: 調用者的編譯參數。

由於 prefix之類的變數是在軟體包configure時才決定的,不能直接寫死在pc檔案中。我們可以讓configure根據模板檔案來產生。

模板檔案名稱為base.pc.in,內容為:

prefix=@prefix@exec_prefix=${prefix}libdir=${prefix}/libincludedir=${prefix}/include Name: @PACKAGE_NAME@Description: a basic library.Version: @VERSION@Requires:Libs: -L${libdir} -lbaseCflags: -I${includedir}/base

這個模板檔案和Makefile.in的替換規則一樣,用兩個@@括起來的變數會替換成configure檢測出來的值,@prefix@等變數是 標準的變數。

修改一下base/Makefile.am,增加下列兩行代碼:

pkgconfigdir=${libdir}/pkgconfig
pkgconfig_DATA=base.pc

這是安裝資料檔案的方法,pkgconfig不是關鍵字,取個描述性的名稱就好了。dir和_DATA是關鍵字,它們有相同的首碼,前者表示安裝的 目錄,後者表示要安裝的檔案。按照慣例,pc檔案安裝到${libdir}/pkgconfig下。

修改configure.in,增加輸入出檔案base.pc
AC_OUTPUT([base.pc])

放到AC_CONFIG_FILES也可以,它告訴configure指令碼要產生的檔案。

重新運行configure後會產生base.pc,內容為:

prefix=/home/lixianjing/usr/localexec_prefix=${prefix}libdir=${prefix}/libincludedir=${prefix}/includeName: baseDescription: a basic library.Version: 0.1Requires:Libs: -L${libdir} -lbaseCflags: -I${includedir}/base

(prefix與configure時指定的prefix參數一致。)

在下一節中,我們再學習調用者如何使用pc檔案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.