pkg-config 用法 – 自動產生 compile flags

雖然是一個工作10幾年的人了,但是不懂的東西還是很多。平日編 code 都不深究那些需要的參數是哪來的,但有時還是會有個疑問,實際上是怎麼回事。直到2天前在研究一個 DBus 的程式怎麼編譯,才獲得了一些相關的知識。

系統內的 Library 資訊

當我們下載一個 opensource 的 package 下來時,透過 automake 的 configure 腳本可以自動的檢查系統是否具備編譯所需環境,並在make編譯完成後進行make install安裝。make install 的過程中會複製相關的檔案到不同的位置,如執行檔、文件、動態聯結檔等。長久才下,自己曾經裝了哪些 library 都不太清處了。

其實,在 Linux 下有一套 Library 的管理工具 pkg-config,按照其架構所安裝的 Library 就可以透過 pkg-config 來查看。這邊講的訊息,都可以直接從 man pkg-config 所看到。pkg-config 的功能簡表,則用 pkg-config –help 就可以看到。

pkg-config 的 help

列出所有的 Library

要列出已安裝的 Library 列表,只要下達下面命令,即可列出所有的套件名稱

已安裝的 Libraries

產生編譯時的 include 與 library 參數

當我們編譯程式時,如果還要指定所有所需 Library 的資訊時(include / library 目錄),就有點累了。此時,pkg-config 就可以派上用途了,它可以為我們列出指定 library 所需的參數。以這個 DBus-Example為例,當用 gcc 去編譯時,會發現它找不到 “dbus/dbus.h” 這個檔案。即使我們安裝了其所需的 dbus library (透過命令 sudo apt-get install libdbus-1-dev) 之後,仍然是出現相同的錯誤。

缺少 libdbus header

此時,我們只要將編譯命令的最後面加上 pkg-config的訊息,就可以編譯成功。

可以看見,最大的差別就是後面的 pkg-config 命令了,這個命令會產生後面指定 Library 所需的 include 和 library 的參數。如果我們直接執行 pkg-config 部份的命令,就可以看出它所產生出來的內容。

pkg-config 展開的參數

因此,當你知道你的程式所需的 Library,剩下所需的參數,就可交由 pkg-config 來自行產生。當然前提是你的 Library 要已經安裝了,一般而言從header檔的名字就可看出其所需的 library。以上例的 dbus,就可透過 apt-cache search dbus 判定所需的 library 是哪個套件。如果還是沒頭緒,就上網搜搜看了。

搜尋 dbus 的 Library

Library 資訊出處

上面指的這些 Library 資訊,實際上是儲存在多處的。每個 Library 的資訊,都會儲存在一個 .pc 的檔案內, pkg-config 的功能就是去把這些檔案找出來,以供使用者運用。這些 .pc 一般會放在 pkgconfig  目錄下,要列出所有的 pkgconfig 目錄可以使用 pkg-config –variable pc_path pkg-config 來列出來。

列出 pkgconfig 目錄

而本文所用到的 dbus 檔案,則位於 /usr/lib/i386-linux-gnu/pkgconfig/dbus-1.pc

dbus-1.pc 內容

自行指定 pkgconfig 搜尋位置

有時候自行編譯了一些 local 的 library 時,pkg-config 並無法搜尋到其中的 .pc 檔,這時就可以用 PKG_CONFIG_PATH 的這個環境變數指向要搜尋的目錄,這樣用 pkg-config 也就可以產生出所需要的變數了。

這個環境變數在編譯 opensource package 時常常會用到,因為這些 package 常常有相依性,因此常常要指定自行編譯 library 位置。

 

結語

工作裡, Linux 環境用的多瞭解的少,所以連這麼基本的問題,工作了十數年了到現在才有一點瞭解。其它諸如 automake, yacc, cmake 等之類的,其實也是些常見但又不解的東西。Linux 包含太多東西了,專業分工的時代,會用就好了,其它也只能等到碰到再學囉~

Leave a Reply