pkg config 學習筆記

2021-09-19 11:06:51 字數 4687 閱讀 6838

術語對照表:

引數 - option

選項 - flag

在編譯和鏈結時,提供必要的庫檔案細節。元資料儲存在 pkg-config 檔案裡面,檔案字尾.pc,檔案需要存放在 pkg-config 工具能夠找到的特定位置。

prefix=/usr/local

exec_prefix=$

includedir=$/include

libdir=$/lib

name: foo

description: the foo library

version: 1.0.0

cflags: -i$/foo

libs: -l$ -lfoo

關鍵字定義比如name:***,後面跟著乙個冒號:和值。關鍵字由 pkg-config 工具定義。

變數比如prifix=***,後面跟著乙個等號=和值。變數一方面可以簡化.pc檔案的書寫,一方面可以儲存一些 pkg-config 工具無法覆蓋的資料。

description:對包的乙個簡要描述。

version:包的版本號

requires:這個包依賴的包的列表。依賴的包的版本號可以通過比較操作符指定(例如 = 、<=)

requires.private:這個包依賴的包的列表。但是目標應用無法使用這些包。

conflicts:可選字段,描述哪些包與此包衝突。

cflags:不支援 pkg-config 的一些編譯選項和庫依賴。如果依賴的庫支援 pkg-config ,那麼這個庫就應該放到前面的 requires 或者 requires.private 欄位中去。

在給乙個包建立 pkg-config 檔案(後面簡稱為 pc 檔案)的時候首先要決定這些檔案的發布方式,最好是每個庫都有乙個對應的 pc 檔案,這樣每個包至少有跟庫的數量一致的 pc 檔案。

name、description、url欄位都是純資訊,很容易填。 version 欄位有一點點麻煩,需要確保該資料能被使用者所使用。pkg-config 使用 rpm 的演算法來進行版本比較。建議使用通過句點.分開的十進位制數,如果使用字母的話會出現不可預知的錯誤。版本號必須單調遞增,並且足以制定這個庫檔案。通常使用包的版本號就足夠了,而且這樣方面使用者進行追蹤。

在介紹更有用的字段之前,先介紹一下變數的定義。變數最常見的用途是指定安裝路徑,使用變數可以使元資料字段保持簡潔。變數是遞迴地進行展開的,因此跟自動生成的路徑一起使用十分有用(這句話沒看懂)。

prefix=/usr/local

includedir=$/include

cflags: -i$/foo

pkg-config 裡面最重要的元資料字段是 requires、 requires.private 、 cflags 、 libs 和 libs.private 。它們定義了外部專案編譯鏈結這個庫時所需要元資料。

requires 和 requires.private 定義了這個庫所需的其他模組。通常建議使用 require 的 private 變體,以避免把不必要的庫暴露給使用者程式。如果使用者程式不會用到依賴庫的符號,那麼這個庫經不應該被直接鏈結到使用者程式上。更詳盡的討論參見 overlinking 。

因為 pkg-config 總是暴露 requires 庫的鏈結選項,所以這些模組會成為程式的直接依賴。另一方面,require.private 中的庫在靜態鏈結的時候只會被包含。因此,通常比較合適的做法是僅在 requires 字段新增同乙個包裡面的模組。 (老外的寫作水平也是堪憂啊,各種 包、模組、庫詞彙混雜在一起使用。)

libs 包含使用庫所必需的鏈結選項。此外,libs 和 libs.private 還包含 pkg-config 不支援的其他庫的鏈結選項。同樣的,推薦把外部庫的鏈結選項放到 libs.private 字段裡面去。

cflags 包含這個庫所必需的編譯選項。與 libs 不同的是這個字段沒有 private 變體。因為不管是怎麼樣的鏈結場景,資料型別和巨集定義都是需要的。

假設系統安裝了 .pc 檔案,那麼 pkg-config 工具就是用來抽取元資料的。執行pkg-config --help可以檢視其各個引數的簡要描述。更詳細的描述可以在 pkg-config(1) 手冊頁中找到。本節會簡要介紹一些常用的情況。

假設乙個系統有個兩個模組,foo 和 bar 。他們的 pc 檔案可以是這樣:

foo.pc:

prefix=/usr

exec_prefix=$

includedir=$/include

libdir=$/lib

name: foo

description: the foo library

version: 1.0.0

cflags: -i$/foo

libs: -l$ -lfoo

bar.pc:

prefix=/usr

exec_prefix=$

includedir=$/include

libdir=$/lib

name: bar

description: the bar library

version: 2.1.2

requires.private: foo >= 0.7

cflags: -i$

libs: -l$ -lbar

模組的版本號可以通過--modversion引數檢視

$ pkg-config --modversion foo

1.0.0

$ pkg-config --modversion bar

2.1.2

每個模組所需要的鏈結選項可以通過--libs引數檢視

$ pkg-config --libs foo

-lfoo

$ pkg-config --libs bar

-lbar

注意 pkg-config 隱去了部分 libs 中的字段。這是因為當它看到 -l 選項時,知道 $ 路徑 /usr/lib 是系統鏈結器的查詢路徑。使用 -l 可以避免 pkg-config 干涉鏈結操作。

而且,儘管 foo 被 bar 所依賴,foo 的鏈結選項卻沒有輸出。這是因為 foo 並不是使用者應用直接需要的模組。而如果要靜態鏈結乙個 bar 應用,需要同時設定兩個鏈結選項。

$ pkg-config --libs --static bar

-lbar -lfoo

pkg-config 需要把兩個鏈結選項都輸出來,確保靜態鏈結的應用能夠找到所有需要的符號。另一方面,它會把所有 cflags

輸出。

$ pkg-config --cflags bar

-i/usr/include/foo

$ pkg-config --cflags --static bar

-i/usr/include/foo

另乙個常用的引數--exists,可以用來檢測乙個模組的可用性。

$ pkg-config --exists foo

$ echo $?

0

pkg-config 的乙個最優秀的特性是提供了版本檢測。它可以檢測是否存在滿足條件的版本。

$ pkg-config --libs "bar >= 2.7"

requested 'bar >= 2.7' but version of bar is 2.1.2

有些命令在使用--print-errors引數後會進行更詳盡的輸出。

$ pkg-config --exists --print-errors xoxo

package xoxo was not found in the pkg-config search path.

perhaps you should add the directory containing `xoxo.pc'

to the pkg_config_path environment variable

no package 'xoxo' found

$ pkg-config --modversion hello

package hello was not found in the pkg-config search path.

perhaps you should add the directory containing `hello.pc'

to the pkg_config_path environment variable

no package 'hello' found

$ export pkg_config_path=/usr/local/lib/pkgconfig

$ pkg-config --modversion hello

1.0.0

把 pkg-config 模組整合到使用者專案中的時候,使用自動配置(autoconf)的巨集可以簡化這個過程。

pkg config的學習之路

pkg config是編譯應用程式和庫時使用的輔助工具。它可以幫助我們在命令列中插入正確的編譯器選項,以便應用程式可以使用諸如gcc o test test.c pkg config libs cflags glibc 2.29 的命令,其中 cflags和 libs分別指定cflags引數和庫檔案...

pkg config用法詳解

我們在用第三方庫的時候,經常會用到pkg config這個東西來編譯程式。那pkg config究竟是什麼呢?本博文簡單地說一下。對於乙個比較大第三方庫,其標頭檔案和庫檔案的數量是比較多的。如果我們乙個個手動地寫,那將是相當麻煩的。所以,pkg config就應運而生了。pkg config能夠把這...

pkg config 編譯安裝

由於大部分的開源工程都需要用到pkg config,因此今天在這講解一下pkg config for mac 安裝過程.1.檢測環境是否已安裝pkg config 再命令列中輸入 pkg config 若未安裝,則提示命令未找到.2.安裝pkg config pkg config 0.28.tar....