C/C++开发中使用pkg-config来引用依赖库
在使用C/C++进行开发的过程中,经常需要引用其它的库,可能是系统已经安装好的,也可能是其它的外部库。
如果是系统支持的库,可能在不同的系统下,其路径也不相同,在项目开发的时候跨平台将会是一个问题。比如,同样是使用Glib库,在MinGW下使用与Linux下使用,它们的路径不一样;即使都在Linux下,不同的Linux发行版本可能路径也不一样。这就导致编译配置很难跨平台或者跨系统。
pkg-config的出现让此问题不再是问题。
一、什么是pkg-config
pkg-config是一个命令行工具,通过它,可以知道库的include路径、lib路径以及需要链接的库名,这三样信息是C/C++开发必不可少的信息。
其实这些信息都是以文本文件(*.pc)的存放在系统中的,64位Linux一般在/lib64/pkgconfig
、/usr/lib64/pkgconfig
、/usr/local/lib64/pkgconfig
,32位Linux一般在/lib/pkgconfig
、/usr/lib/pkgconfig
、/usr/local/lib/pkgconfig
,MinGW一般在MinGW安装目录的/lib/pkgconfig
下。可以看一下MinGW下的glib-2.0.pc
内容:
1prefix=/mingw64
2includedir=${prefix}/include
3libdir=${prefix}/lib
4
5bindir=${prefix}/bin
6glib_genmarshal=${bindir}/glib-genmarshal
7gobject_query=${bindir}/gobject-query
8glib_mkenums=${bindir}/glib-mkenums
9
10Name: GLib
11Description: C Utility Library
12Version: 2.76.1
13Requires.private: libpcre2-8 >= 10.32
14Libs: -L${libdir} -lglib-2.0 -lintl
15Libs.private: -lws2_32 -lole32 -lwinmm -lshlwapi -luuid -lm
16Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
可以看到里面有很多信息,但最重要的是在编译链接时所需要的信息Libs
和Cflags
,它会自动把所依赖的其它库给包含进来,非常省事。
二、安装pkg-config
有的系统一般会在安装系统时就安装好了,不同的系统,安装包的名字可能会有一些差异,下面列出常用的几种系统的安装:
- CentOS
sudo yum install pkgconfig
- Ubuntu
sudo apt install pkg-config
- MinGW64
pacman -S mingw-w64-x86_64-pkg-config
三、使用pkg-config得到编译链接所需信息
在Shell中使用下面的命令即可得到glib-2.0
的相关信息:
pkg-config glib-2.0 --cflags --libs
在Ubuntu下输出:
1-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0
如果想要知道系统中哪些库是支持pkg-config的,可以使用如下命令获取:
pkg-config --list-all
四、开发项目中使用pkg-config
假设有一个main.c
的文件:
1#include <glib.h>
2
3int main(int argc, char ** argv)
4{
5 GList* l = g_list_alloc();
6 g_list_free(l);
7 return 0;
8}
只需要使用如下命令即可编译链接:
1 gcc -o main main.c `pkg-config glib-2.0 --cflags --libs`
非常方便省事。注意:MinGW只能在Shell控制台使用,在Windows的控制台中使用会报错:
1gcc: error: unrecognized command-line option '--cflags'
2gcc: error: unrecognized command-line option '--libs`'
如果是使用CMake也非常方便,只需要在CMakeLists.txt中添加如下指令:
1find_package(PkgConfig REQUIRED)
2pkg_check_modules (GLIB2 REQUIRED IMPORTED_TARGET glib-2.0)
3target_link_libraries(${PROJECT_NAME} PkgConfig::GLIB2)
其中GLIB2
是一个别名,可以任意取,后面就可以使用这个别名来引用。
如果想要在CMake时输出相关信息,添加如下指令:
1message(STATUS "GLIB2_INCLUDE_DIRS: ${GLIB2_INCLUDE_DIRS}")
2message(STATUS "GLIB2_LIBRARY_DIRS: ${GLIB2_LIBRARY_DIRS}")
3message(STATUS "GLIB2_LIBRARIES: ${GLIB2_LIBRARIES}")
下面给出完整CMakeLists.txt
:
1cmake_minimum_required(VERSION 3.12.0)
2project(demo VERSION 0.1.0)
3
4add_executable(${PROJECT_NAME} main.c)
5
6find_package(PkgConfig REQUIRED)
7pkg_check_modules (GLIB2 REQUIRED IMPORTED_TARGET glib-2.0>=2.70)
8target_link_libraries(${PROJECT_NAME} PkgConfig::GLIB2)
9
10message(STATUS "GLIB2_INCLUDE_DIRS: ${GLIB2_INCLUDE_DIRS}")
11message(STATUS "GLIB2_LIBRARY_DIRS: ${GLIB2_LIBRARY_DIRS}")
12message(STATUS "GLIB2_LIBRARIES: ${GLIB2_LIBRARIES}")
这里可以指定需要引入库的版本,glib-2.0>=2.70
表示引用的库版本要求在2.70及以上版本。
有帮助的话,欢迎点赞收藏!
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2023/2023-04-20-C_C++开发中使用pkg-config来引用依赖库/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。