1. 程式人生 > >乾貨:pkg-config工具在實際工程中的用法

乾貨:pkg-config工具在實際工程中的用法

    在如今這個開源的環境裡,想要開發某個功能,我們都會下意識的上網搜尋有沒有開源庫,如果有開源庫,那麼好,下載下來給它編譯好,使用。但是在使用過程中,你是否遇到不知如何將第三方庫編譯,連結到自己的工程中?怎麼改makefile就是改不好?是否看到開源庫lib/中pkgconfig資料夾,想都沒想這是幹什麼用的,開啟.pc檔案也不知所云?那麼好,今天我就總結下開源庫中pkgconfig資料夾中.pc檔案的作用,以及如何用pkg-config工具將開源庫整合到自己的工程中去。 1、pkg-config工具的作用     pkg-config簡單的說就是向用戶提供相應庫的路徑,版本號,標頭檔案路徑等資訊的綜合呼叫程式。筆者使用的是Ubuntu系統,我們以OpenEXR庫為例看看pkg-config執行的結果,在shell命令列輸入:

顯示資訊為:-I/usr/include/OpenEXR -lIlmImf -lImath -lHalf -lIex -lIexMath -lIlmThread -lpthread 這是什麼呀? -I/usr/include/OpenEXR 這不就是我們用gcc編譯時的CFLAGS引數嗎? -lIlmImf -lImath -lHalf -lIex -lIexMath -lIlmThread -lpthread這些不就是gcc在連結時使用的LDFLAGS引數嗎? 因此當我們需要在自己的工程中編譯連結時只需要合理的使用pkg-config工具,把上面那些引數加入到gcc的引數裡即可,這個就是pkg-config工具的核心作用,它會檢查你的庫,產生相應資訊,為你整合某個第三方庫提供便利。
2、*.pc檔案解析   我們知道,第三方庫的使用主要涉及標頭檔案的路徑設定,庫的路徑設定以及動態庫的環境變數設定。一般來講,第三方庫都會提供一個*.pc 檔案,pkg-config程式通過讀取這個*.pc的檔案,獲取了庫的標頭檔案位置和庫的路徑等資訊,然後告知編譯器,實現庫的自動使用。一般來說,*.pc檔案的大體內容如下格式(以筆者最近使用的SQLite3為例):

其中,

  • prefix一般是指定庫的預設安裝路徑
  • exec_prefix一般是指庫的另外指定的安裝路徑
  • inludedir指定庫的標頭檔案路徑
  • libdir指定庫的lib檔案的路徑
  • Name指定庫的名稱,比如筆者使用的SQLite資料庫
  • Description表示庫的描述
  • Version是版本號
  • Cflags是gcc連結標頭檔案的指令,以-I緊接標頭檔案路徑設定
  • Libs是gcc連結lib檔案的指令, 是-L緊接lib檔案路徑,-l緊接所使用的lib的名字。
3、如何編譯連結到你的工程?     這裡講的是工程,我只講乾貨,編譯單個程式例子網上有很多,就不贅述了。這裡注意,使用pkg-config工具提取庫的編譯和連結引數需要有兩個基本前提: 1)庫本身按章的時候必須提供一個.pc檔案。沒有這個檔案的說明庫不支援pkg-config工具; 2)pkg-config必須要知道去哪找.pc檔案;     對於支援pkg-config工具的庫來說,庫檔案的搜尋路徑實際就是對.pc檔案的搜尋路徑,一般系統的預設搜尋路在/usr/lib/pkgconfig 中,庫的標頭檔案一般在/usr/include中。而個人使用的第三方庫,不能每次編譯後都裝到/usr目錄下吧。所以私有工程在編譯連結第三方庫時可以通過環境變數PKG_CONFIG_PATH來設定,pkg-config工具將按照設定路徑的先後順序進行搜尋,直到找到指定的.pc檔案為止。    所以在私有工程的makefile中,先修改環境變數: export PKG_CONFIG_PATH=/home/水笙/sqlite-autoconf-3130000/build_result/lib/pkgconfig:$PKG_CONFIG_PATH 環境變數設定好後,設定CFLAGS: CFLAGS += `pkg-config --cflags sqlite3` 這裡注意要用``將命令包起來。 然後設定LDFLAGS: LDFLAGS += `pkg-config --libs sqlite3` 基本通過這三步,工程就可以正確的編譯連結第三方庫了。 4、執行時指明共享庫搜尋路徑     我們知道,庫分為靜態庫和共享庫。靜態庫.a就是一些.o檔案的集合,編譯連結後就整合到了你的應用程式中。而共享庫,是在程式執行的時才被使用的,其搜尋路徑是在系統中預先設定的,對於處於搜尋路勁之外的庫,使用的時候必須設定好環境變數LD_LIBRARY_PATH,否則應用程式找不到,筆者將sqlite3庫放到了應用程式資料夾的./lib中,在啟動應用前呼叫下面這句: export LD_LIBRARY_PATH="./lib" 筆者建議,最好將其寫在你的啟動腳本里。 完。