在使用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

可以看到里面有很多信息,但最重要的是在编译链接时所需要的信息LibsCflags,它会自动把所依赖的其它库给包含进来,非常省事。

二、安装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及以上版本。

有帮助的话,欢迎点赞收藏!