在使用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
内容:
prefix=/mingw64
includedir=${prefix}/include
libdir=${prefix}/lib
bindir=${prefix}/bin
glib_genmarshal=${bindir}/glib-genmarshal
gobject_query=${bindir}/gobject-query
glib_mkenums=${bindir}/glib-mkenums
Name: GLib
Description: C Utility Library
Version: 2.76.1
Requires.private: libpcre2-8 >= 10.32
Libs: -L${libdir} -lglib-2.0 -lintl
Libs.private: -lws2_32 -lole32 -lwinmm -lshlwapi -luuid -lm
Cflags: -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下输出:
-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
的文件:
#include <glib.h>
int main(int argc, char ** argv)
{
GList* l = g_list_alloc();
g_list_free(l);
return 0;
}
只需要使用如下命令即可编译链接:
gcc -o main main.c `pkg-config glib-2.0 --cflags --libs`
非常方便省事。注意:MinGW只能在Shell控制台使用,在Windows的控制台中使用会报错:
gcc: error: unrecognized command-line option '--cflags'
gcc: error: unrecognized command-line option '--libs`'
如果是使用CMake也非常方便,只需要在CMakeLists.txt中添加如下指令:
find_package(PkgConfig REQUIRED)
pkg_check_modules (GLIB2 REQUIRED IMPORTED_TARGET glib-2.0)
target_link_libraries(${PROJECT_NAME} PkgConfig::GLIB2)
其中GLIB2
是一个别名,可以任意取,后面就可以使用这个别名来引用。
如果想要在CMake时输出相关信息,添加如下指令:
message(STATUS "GLIB2_INCLUDE_DIRS: ${GLIB2_INCLUDE_DIRS}")
message(STATUS "GLIB2_LIBRARY_DIRS: ${GLIB2_LIBRARY_DIRS}")
message(STATUS "GLIB2_LIBRARIES: ${GLIB2_LIBRARIES}")
下面给出完整CMakeLists.txt
:
cmake_minimum_required(VERSION 3.12.0)
project(demo VERSION 0.1.0)
add_executable(${PROJECT_NAME} main.c)
find_package(PkgConfig REQUIRED)
pkg_check_modules (GLIB2 REQUIRED IMPORTED_TARGET glib-2.0>=2.70)
target_link_libraries(${PROJECT_NAME} PkgConfig::GLIB2)
message(STATUS "GLIB2_INCLUDE_DIRS: ${GLIB2_INCLUDE_DIRS}")
message(STATUS "GLIB2_LIBRARY_DIRS: ${GLIB2_LIBRARY_DIRS}")
message(STATUS "GLIB2_LIBRARIES: ${GLIB2_LIBRARIES}")
这里可以指定需要引入库的版本,glib-2.0>=2.70
表示引用的库版本要求在2.70及以上版本。
有帮助的话,欢迎点赞收藏!