永远写不完的故事 發表於 2025-8-6 18:03:00

pkg-config【Linux包管理工具】

<p>PkgConfig(<code>pkg-config</code>)是一个在 Linux/Unix 开发中<strong>管理库的编译和链接参数的工具</strong>,能自动生成正确的头文件路径(<code>-I</code>)、库路径(<code>-L</code>)和链接库名称(<code>-l</code>)等标志。以下为详细使用指南:</p>
<hr>
<h2>pkg-config命令使用</h2>
<h3><strong>1. 安装</strong></h3>
<ul>
<li>
<p><strong>Debian/Ubuntu</strong>:</p>
<pre><code class="language-bash">sudo apt-get install pkg-config
</code></pre>
</li>
<li>
<p><strong>CentOS/RHEL</strong>:</p>
<pre><code class="language-bash">sudo yum install pkg-config
</code></pre>
</li>
</ul>
<hr>
<h3><strong>2. 基本命令</strong></h3>
<ul>
<li>
<p><strong>检查库是否存在</strong>:</p>
<pre><code class="language-bash">pkg-config --exists &lt;库名&gt;# 返回 0 表示存在
</code></pre>
<ul>
<li>
<p>命令实际使用时的表现是:</p>
<ul>
<li><strong>成功</strong>:返回状态码 <code>0</code>,<strong>无输出</strong>。</li>
<li><strong>失败</strong>:返回状态码 <code>非0</code>,<strong>默认无输出</strong>(需 <code>--print-errors</code>显示错误)。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>获取库版本</strong>:</p>
<pre><code class="language-bash">pkg-config --modversion &lt;库名&gt;# 输出版本号(如 2.66.0)
</code></pre>
</li>
<li>
<p><strong>提取编译选项(头文件路径)</strong> :</p>
<pre><code class="language-bash">pkg-config --cflags &lt;库名&gt;# 输出 -I/usr/include/glib-2.0
</code></pre>
<ul>
<li>默认过滤系统路径<code>/usr/include</code>​</li>
</ul>
</li>
<li>
<p><strong>提取链接选项(库路径及名称)</strong> :</p>
<pre><code class="language-bash">pkg-config --libs &lt;库名&gt;# 输出 -L/usr/lib -lglib-2.0
</code></pre>
</li>
<li>
<p><strong>同时获取编译和链接选项</strong>:</p>
<pre><code class="language-bash">pkg-config --cflags --libs &lt;库名&gt;
</code></pre>
</li>
</ul>
<hr>
<h3><strong>3. 配置搜索路径(PKG_CONFIG_PATH)</strong></h3>
<p>若库安装在非标准路径(如 <code>/usr/local/lib</code>),需设置环境变量:</p>
<pre><code class="language-bash">export PKG_CONFIG_PATH=/custom/path/lib/pkgconfig:$PKG_CONFIG_PATH
</code></pre>
<ul>
<li>
<p><strong>示例</strong>:</p>
<pre><code class="language-bash">export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
</code></pre>
</li>
<li>
<p><strong>永久生效</strong>:将命令添加到 <code>~/.bashrc</code>或 <code>/etc/profile</code>。</p>
</li>
</ul>
<hr>
<h3><strong>4. 在编译命令中使用</strong></h3>
<p>在 <code>gcc/g++</code>中直接嵌入 <code>pkg-config</code>命令:</p>
<pre><code class="language-bash">gcc program.c $(pkg-config --cflags --libs glib-2.0) -o program
</code></pre>
<p>或使用反引号:</p>
<pre><code class="language-bash">gcc program.c `pkg-config --cflags --libs glib-2.0` -o program
</code></pre>
<p><strong>优势</strong>:自动处理依赖(如 <code>glib-2.0</code>依赖的其他库),避免手动指定路径。</p>
<hr>
<h3><strong>5. 高级用法</strong></h3>
<ul>
<li>
<p><strong>静态链接</strong>:</p>
<pre><code class="language-bash">pkg-config --static --libs &lt;库名&gt;# 输出静态库链接标志
</code></pre>
</li>
<li>
<p><strong>检查最小版本</strong>:</p>
<pre><code class="language-bash">pkg-config --atleast-version=2.0.0 glib-2.0# 版本≥2.0.0 返回 0
</code></pre>
</li>
<li>
<p><strong>列出所有可用库</strong>:</p>
<pre><code class="language-bash">pkg-config --list-all
</code></pre>
</li>
</ul>
<hr>
<h3><strong>6. 为自定义库创建</strong> <strong>.pc</strong> <strong>文件</strong></h3>
<p>若开发新库,需在 <code>/usr/local/lib/pkgconfig/</code>下创建 <code>&lt;库名&gt;.pc</code>文件:</p>
<pre><code class="language-ini">prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
</code><p><code class="language-ini">Name: mylib<br>
Description: Custom Library<br>
Version: 1.0.0<br>
Libs: -L<span class="math inline">\({libdir} -lmylib
Cflags: -I\)</span>{includedir}/mylib<br>
</code></p></pre><p></p>
<p><strong>关键字段</strong>:</p>
<ul>
<li>​<code>Name</code>:库标识名(<code>pkg-config</code>查询用)。</li>
<li>​<code>Libs</code>/<code>Cflags</code>:链接和编译标志。</li>
<li>​<code>Requires</code>:声明依赖库(如 <code>Requires: glib-2.0</code>)<br>
。</li>
</ul>
<hr>
<h3><strong>7. 常见问题</strong></h3>
<ul>
<li>
<p><strong>错误提示 "Package not found"</strong> :</p>
<ul>
<li>确认库的开发包已安装(如 <code>libpng-dev</code>)。</li>
<li>检查 <code>.pc</code>文件是否在 <code>PKG_CONFIG_PATH</code>或默认路径(<code>/usr/lib/pkgconfig</code>)。</li>
</ul>
</li>
<li>
<p><strong>版本冲突</strong>:使用 <code>--exact-version</code>或 <code>--max-version</code>限制版本范围</p>
</li>
</ul>
<hr>
<h2><strong>pkg-config在cmake中使用</strong></h2>
<h3><strong>1. 基础使用流程</strong></h3>
<h4><strong>步骤 1:启用 PkgConfig 模块</strong></h4>
<p>在 <code>CMakeLists.txt</code>中调用 <code>find_package</code>加载 <code>PkgConfig</code>模块:</p>
<pre><code class="language-cmake">cmake_minimum_required(VERSION 3.10)
project(MyProject LANGUAGES CXX)
find_package(PkgConfig REQUIRED)# 确保系统已安装 pkg-config
</code></pre>
<h4><strong>步骤 2:查找依赖库</strong></h4>
<p>使用 <code>pkg_check_modules</code>或 <code>pkg_search_module</code>定位库:</p>
<ul>
<li>​<strong>​<code>pkg_check_modules</code>​</strong>:要求所有指定库均存在(严格匹配)。</li>
<li>​<strong>​<code>pkg_search_module</code>​</strong>:只需匹配列表中任意一个库(宽松匹配)。</li>
</ul>
<pre><code class="language-cmake"># 查找 GTK 3.0 和 Glib 2.0(两者必须存在)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0 glib-2.0)
<h1 id="查找-zeromq任一别名匹配即可">查找 ZeroMQ(任一别名匹配即可)</h1>
</code><p><code class="language-cmake">pkg_search_module(ZeroMQ REQUIRED IMPORTED_TARGET libzeromq libzmq)<br>
</code></p></pre><p></p>
<h4><strong>步骤 3:链接库到目标</strong></h4>
<p>使用生成的变量或导入目标(推荐)配置编译选项:</p>
<pre><code class="language-cmake">add_executable(my_app main.cpp)
# 传统变量方式
target_include_directories(my_app PRIVATE ${GTK3_INCLUDE_DIRS})
target_link_libraries(my_app PRIVATE ${GTK3_LIBRARIES})
</code></pre>
<ul>
<li>使用<code>target_include_directories</code>时,权限是<strong>必要的</strong>,<code>PRIVATE INTERFACE PIUBLIC</code>​</li>
<li>对于<code>target_link_libraries</code>,权限是<strong>非必要的</strong></li>
<li>​<code>GTK3_INCLUDE_DIRS</code>与<code>GTK3_LIBRARIES</code>是根据步骤2查找依赖库时定义的变量名作为前缀生成的两个变量,其分别存储了查找到的库的头文件路径列表和链接库列表。</li>
</ul>
<hr>
<h3>2 <strong>. 配置 PKG_CONFIG_PATH</strong></h3>
<p>若依赖库安装在非标准路径(如 <code>/usr/local/lib</code>),需通过环境变量扩展搜索路径:</p>
<pre><code class="language-cmake"># 在 CMakeLists.txt 中临时设置
set(ENV{PKG_CONFIG_PATH} "/custom/path/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")
</code></pre>
<p>或在终端中设置:</p>
<pre><code class="language-bash">export PKG_CONFIG_PATH="/custom/path/lib/pkgconfig:$PKG_CONFIG_PATH"
</code></pre>
<p>此操作确保 <code>pkg-config</code>能定位到自定义安装的 <code>.pc</code>文件。</p>
<hr>
<h3>3 <strong>. 高级特性与技巧</strong></h3>
<h4><strong>静态链接</strong></h4>
<p>通过 <code>--static</code>标志获取静态库链接选项:</p>
<pre><code class="language-cmake">pkg_check_modules(GTK3_STATIC REQUIRED IMPORTED_TARGET gtk+-3.0)
set_target_properties(PkgConfig::GTK3_STATIC PROPERTIES INTERFACE_LINK_LIBRARIES "${GTK3_STATIC_STATIC_LDFLAGS}")
</code></pre>
<h4><strong>版本控制</strong></h4>
<p>检查依赖库的版本兼容性:</p>
<pre><code class="language-cmake">pkg_check_modules(GLIB REQUIRED glib-2.0&gt;=2.60)
</code></pre>
<p>若版本低于 2.60,配置将失败。</p>
<h4><strong>依赖传递</strong></h4>
<p>​.pc文件中的 <code>Requires</code>字段声明依赖关系,<code>pkg-config</code>会自动递归解析。例如 <code>harfbuzz.pc</code>依赖 <code>freetype2</code>,生成的变量会包含所有层级依赖的编译参数。</p>
<hr>
<h3>4 <strong>. 常见问题与解决</strong></h3>
<ul>
<li>
<p><strong>错误:<strong>​</strong>​<code>Package not found</code>​</strong>​</p>
<ul>
<li>确认库的开发包已安装(如 <code>libzmq-dev</code>)。</li>
<li>检查 <code>.pc</code>文件是否在 <code>PKG_CONFIG_PATH</code>或默认路径(<code>/usr/lib/pkgconfig</code>)。</li>
</ul>
</li>
<li>
<p><strong>CMake 版本兼容性</strong><br>
​<code>IMPORTED_TARGET</code>要求 CMake ≥ 3.6,低版本需手动配置变量。</p>
</li>
<li>
<p><strong>与</strong> <strong>​<code>find_package</code>​</strong>​<strong>的选用原则</strong></p>
<ul>
<li>优先使用库提供的 <code>Config.cmake</code>(<code>find_package</code>)。</li>
<li>若无 CMake 支持,则用 <code>pkg-config</code>(尤其适用于 Linux 常见库如 GTK、OpenSSL)。</li>
</ul>
</li>
</ul>
<hr>
<p>‍</p><br><br>
来源:https://www.cnblogs.com/kindledawn/p/19025606/pkgconfig-2iyu7e
頁: [1]
查看完整版本: pkg-config【Linux包管理工具】