系列文章:
automake學(xué)習(xí)筆記 - helloworld
automake學(xué)習(xí)筆記 - 模塊化編譯
automake學(xué)習(xí)筆記 - 安裝與發(fā)布
automake學(xué)習(xí)筆記 - 交叉編譯
辛辛苦苦寫(xiě)出來(lái)的代碼當(dāng)然是需要發(fā)布出來(lái)給自己或者別人去使用的。這篇文章就談一談發(fā)布相關(guān)的東西吧。
安裝
軟件在編譯完后就需要進(jìn)行安裝刨摩。configure生成的Makefile支持install志衣。使用make install 命令就可以將編譯出來(lái)的軟件安裝到系統(tǒng)中玛臂。
如果沒(méi)有做配置秕硝,默認(rèn)會(huì)安裝到/usr/local中,當(dāng)然如果需要的話也可以使用configure的--prefix參數(shù)指定安裝的路徑,如在build中執(zhí)行下面的命令就可以將build目錄指定為安裝目錄:
../configure --prefix=`pwd`
之后再執(zhí)行下面的安裝命令,工程在編譯完后就會(huì)安裝到build目錄下池充。安裝完畢之后可以看到build里面多了bin和lib兩個(gè)目錄
make install
bin目錄下是編譯出來(lái)的可執(zhí)行文件example,而lib目錄下就是編譯出來(lái)的依賴庫(kù):
-rw-r--r-- 1 linjw linjw 263K 3月 22 13:44 libeasylog.a
-rwxr-xr-x 1 linjw linjw 985 3月 22 13:44 libeasylog.la
lrwxrwxrwx 1 linjw linjw 19 3月 22 13:44 libeasylog.so -> libeasylog.so.0.0.0
lrwxrwxrwx 1 linjw linjw 19 3月 22 13:44 libeasylog.so.0 -> libeasylog.so.0.0.0
-rwxr-xr-x 1 linjw linjw 143K 3月 22 13:44 libeasylog.so.0.0.0
編譯出來(lái)的libeasylog.so.0.0.0就可以直接拿出去給其他人使用了
卸載
卸載的話很簡(jiǎn)單,只需要執(zhí)行下面的命令就行了
make uninstall
當(dāng)然你也可以選擇手動(dòng)去將安裝的文件一個(gè)個(gè)刪除,但是這樣既麻煩又容易漏刪或者錯(cuò)刪
libtool 庫(kù)版本號(hào)系統(tǒng)
我們可以看到編譯出來(lái)的so庫(kù)是帶版本號(hào)的旋膳,默認(rèn)0.0.0,當(dāng)然我們也能直接忽略版本號(hào)(某些可動(dòng)態(tài)加載的的插件模塊可能不需要版本號(hào)):
lib_LTLIBRARIES = libeasylog.la
libeasylog_la_SOURCES = cout_log_interface.cpp \
easy_log.cpp
libeasylog_la_LDFLAGS = -avoid-version
這樣生成安裝的so庫(kù)就不會(huì)帶版本號(hào)了:
-rw-r--r-- 1 linjw linjw 263K 3月 26 11:27 libeasylog.a
-rwxr-xr-x 1 linjw linjw 975 3月 26 11:27 libeasylog.la
-rwxr-xr-x 1 linjw linjw 143K 3月 26 11:27 libeasylog.so
當(dāng)然,絕大部分的庫(kù)都是需要帶上版本號(hào)的途事。每個(gè)系統(tǒng)的庫(kù)版本機(jī)制都不一樣,libtool通過(guò)一種抽象的版本機(jī)制最終在創(chuàng)建庫(kù)的時(shí)候才映射到具體的系統(tǒng)版本機(jī)制上验懊。這是為了方便在交叉編譯的時(shí)候可以用一種機(jī)制去管理不同平臺(tái)上的各種版本機(jī)制。
libtool 庫(kù)版本號(hào)系統(tǒng)有下面三個(gè)部分:
- current
接口的修改次數(shù)
- revision
上次修改后源碼的修改次數(shù)(注意這里指的是只改動(dòng)了實(shí)現(xiàn),沒(méi)有修改接口,如果改了接口的話應(yīng)該要改current號(hào)尸变,并且把revision置零)
- age
當(dāng)前版本可以向前兼容的版本數(shù)
官方文檔是這么描述這三個(gè)部分的更新規(guī)則的:
Here are a set of rules to help you update your library version information:
- Start with version information of ‘0:0:0’ for each libtool library.
- Update the version information only immediately before a public release of your software. More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster.
- If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
- If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
- If any interfaces have been added since the last public release, then increment age.
- If any interfaces have been removed or changed since the last public release, then set age to 0.
翻譯過(guò)來(lái)就是
- 庫(kù)版本號(hào)應(yīng)該開(kāi)始于0.0.0
- 只有在正式發(fā)布庫(kù)的時(shí)候才更新版本號(hào)以避免版本號(hào)增長(zhǎng)過(guò)快
- 當(dāng)實(shí)現(xiàn)代碼改變的時(shí)候revision加1
- 當(dāng)接口改變(無(wú)論是添加义图,刪除還是修改接口聲明)的時(shí)候current加1,同時(shí)revision重置為0
- 如果庫(kù)只是增加了接口,則age加1
- 如果庫(kù)刪除或者修改了接口聲明,則age重置為0
這三個(gè)值可以用-version-info指定
-version-info current[:revision[:age]]
revision 和 age都可以省略,例如你這樣設(shè)置:
lib_LTLIBRARIES = libeasylog.la
libeasylog_la_SOURCES = cout_log_interface.cpp \
easy_log.cpp
libeasylog_la_LDFLAGS = -version-info 3:12:1
表明接口被修改了三次,第三次修改接口之后又修改了12次源碼,接口可以向前兼容1個(gè)版本
make install 后可以看到lib目錄下生成的庫(kù)長(zhǎng)這樣:
-rw-r--r-- 1 linjw linjw 263K 3月 26 12:11 libeasylog.a
-rwxr-xr-x 1 linjw linjw 987 3月 26 12:11 libeasylog.la
lrwxrwxrwx 1 linjw linjw 20 3月 26 12:11 libeasylog.so -> libeasylog.so.2.1.12
lrwxrwxrwx 1 linjw linjw 20 3月 26 12:11 libeasylog.so.2 -> libeasylog.so.2.1.12
-rwxr-xr-x 1 linjw linjw 143K 3月 26 12:11 libeasylog.so.2.1.12
為啥是libeasylog.so.2.1.12而不是libeasylog.so.3.12.1呢?
原來(lái)這幾個(gè)數(shù)字是這樣計(jì)算的:
庫(kù)名.so.current-age.age.revision
這樣會(huì)引發(fā)一個(gè)問(wèn)題:
假設(shè)你的庫(kù)有兩個(gè)【3:0:1】【4:0:2】召烂。 再假設(shè)在你編譯程序的機(jī)器上安裝了最新的【4:0:2】歌溉, 且你在程序中使用了該版本中新加的接口。當(dāng)你程序編譯好后骑晶, 你ldd發(fā)現(xiàn)你的程序依賴libraryname.so.2痛垛, 同時(shí)你將程序安裝在了只安裝了【3:0:1】的機(jī)器上, 你會(huì)發(fā)現(xiàn)你的程序能搜索到動(dòng)態(tài)庫(kù)桶蛔, 卻在運(yùn)行的時(shí)候發(fā)現(xiàn)未定義的符號(hào)匙头, 因?yàn)椤?:0:1】中沒(méi)有新添加的接口。 故你需要在運(yùn)行機(jī)器上保證安裝了同一主版本號(hào)最新的library仔雷, 以保證你的程序能正確運(yùn)行蹂析。
從 libtool動(dòng)態(tài)庫(kù)版本系統(tǒng)之個(gè)人理解 這篇博客引用
手動(dòng)指定版本號(hào)
我之前了解到的so的命名規(guī)范其實(shí)和libtool的版本號(hào)系統(tǒng)的so庫(kù)命名規(guī)范不一樣:
庫(kù)名.so.主版本號(hào).次版本號(hào).發(fā)布版本號(hào)
官方文檔也有提到這一點(diǎn):
Often, people want to encode the name of the package release into the shared library so that it is obvious to the user what package their programs are linked against. This convention is used especially on GNU/Linux:
trick$ ls /usr/lib/libbfd*
/usr/lib/libbfd.a /usr/lib/libbfd.so.2.7.0.2
/usr/lib/libbfd.so
trick$On ‘trick’, /usr/lib/libbfd.so is a symbolic link to libbfd.so.2.7.0.2, which was distributed as a part of ‘binutils-2.7.0.2’.
Unfortunately, this convention conflicts directly with libtool’s idea of library interface versions, because the library interface rarely changes at the same time that the release number does, and the library suffix is never the same across all platforms.
So, to accommodate both views, you can use the -release flag to set release information for libraries for which you do not want to use -version-info. For the libbfd example, the next release that uses libtool should be built with ‘-release 2.9.0’, which will produce the following files on GNU/Linux:
trick$ ls /usr/lib/libbfd*
/usr/lib/libbfd-2.9.0.so /usr/lib/libbfd.a
/usr/lib/libbfd.so
trick$In this case, /usr/lib/libbfd.so is a symbolic link to libbfd-2.9.0.so. This makes it obvious that the user is dealing with ‘binutils-2.9.0’, without compromising libtool’s idea of interface versions.
Note that this option causes a modification of the library name, so do not use it unless you want to break binary compatibility with any past library releases. In general, you should only use -release for package-internal libraries or for ones whose interfaces change very frequently.
可以使用-release去手動(dòng)指定版本號(hào),雖然官方不推薦用這種方式:
lib_LTLIBRARIES = libeasylog.la
libeasylog_la_SOURCES = cout_log_interface.cpp \
easy_log.cpp
libeasylog_la_LDFLAGS = -release 0.0.3
安裝之后lib目錄如下:
-rwxr-xr-x 1 linjw linjw 143K 3月 26 14:48 libeasylog-0.0.3.so
-rw-r--r-- 1 linjw linjw 263K 3月 26 14:48 libeasylog.a
-rwxr-xr-x 1 linjw linjw 993 3月 26 14:48 libeasylog.la
lrwxrwxrwx 1 linjw linjw 19 3月 26 14:48 libeasylog.so -> libeasylog-0.0.3.so
可以在這里查看完整的項(xiàng)目代碼