pkg-config介绍

这里以gstreamer官方的第一个Tutorials为例子,因为这个问题是在学习gstreamer过程中产生的。

例子的源码我稍微精简了一下,

#include <gst/gst.h>

int main(int argc, char *argv[])
{
    GstElement *pipeline;
    GstBus *bus;
    GstMessage *msg;

    /* Initialize GStreamer */
    gst_init(&argc, &argv);

    /* Build the pipeline */
    pipeline = gst_parse_launch("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm",
                                NULL);

    /* Start playing */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    /* Wait until error or EOS */
    bus = gst_element_get_bus(pipeline);
    msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

    /* See next tutorial for proper error message handling/parsing */
    if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
    {
        g_error("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
                "variable set for more details.");
    }

    /* Free resources */
    gst_message_unref(msg);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

教材给出的编译方式是:

gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`

过往,直接使用gcc编译,引用第三方库一般会采用如下方式:

gcc main.c -o main -Iyour_libs_include_dir -Lyour_libs_search_dir -lyour_libs

通过-I指定头文件搜索路径,解决预编译时的问题,通过-L指定库搜索路径,并且通过-l指定需要链接的库,解决最后的链接问题。如果库安装的路径是标准路径,即gcc默认的库搜索路径,则-L选项可以省略。

而上面那条

`pkg-config --cflags --libs gstreamer-1.0`

是什么意思呢?我们知道shell获得命令执行的输出结果有2种形式,如下:

$(your shell cmd)

`your shell cmd`

显然,它这里用了第二种。那既然是想获得命令的输出,那直接执行,得到如下输出:

a@1:/usr$ pkg-config --cflags --libs gstreamer-1.0

-I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -pthread -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0

得到的就是平时需要我们手动敲的这一长串gcc的参数。对于简单的demo,还可以忍受,但是对于大型项目显然没人愿意手动敲,即便用makefile,也非常恶心,因为你根本不知道要引用的第三方模块需要链接哪些库,甚至这个第三方模块可能还有它自己的依赖库。谁最了解这个第三方库?显然是开发这个库的人,那怎么把你的库的头文件信息,库链接信息,依赖信息给到用库的人?pkg-config就是干这个事的,它是一个配置构建依赖信息的工具,方便开发者配置编译和链接选项。在ubuntu上,pkg-config是一个符号链接,指向的其实是pkgconf。它们会在指定的目录搜索*.pc的文件,通过strace即可分析出来它在哪些目录搜索。

在ubuntu上通过apt install libxx-dev安装的开发版本的库,通常会把它自己的pc文件安装在/usr/lib/x86_64-linux-gnu/pkgconfig,注意,并不是所有库都会这样,因为还有其他的方式管理这些信息,比如cmake的*.cmake文件,这个得看库的开发者提供了哪些方式,当然也可以多种方式都使用,例如Qt5就提供了这两种机制,而gstreamer1.0仅提供了pc这种。而且cmake是可以调用pc这在机制的,这个后续介绍。

man pkgconf或者pkgconf --help可以快速了解一下。选项分为基础选项,检查选项,查询选项。介绍几个常用的选项:

--list-all  #列出搜到到的所有库名
--list-package-names #和上面的差不多,可以得到额外的一个简介信息
--with-path=path  #指定额外的pc文件搜索路径,例如你自己编译的库没安装在默认路径时

--exists    #检查指定的库是否存在,通过$?来判断

--cflags
--libs
posted @ 2023-08-02 16:54  thammer  阅读(161)  评论(0编辑  收藏  举报