Chinaunix首页 | 论坛 | 博客
  • 博客访问: 705384
  • 博文数量: 260
  • 博客积分: 7033
  • 博客等级: 少将
  • 技术积分: 2633
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-13 23:15
文章分类

全部博文(260)

文章存档

2012年(2)

2011年(41)

2010年(78)

2009年(139)

我的朋友

分类: LINUX

2009-05-16 15:22:24

OE在编译程序时,经常会用到pkg-config来查找该应用所依赖的包的有关信息。
使用devshell进入一个应用程序的环境后,查看到环境变量中有4个和PKG_CONFIG相关的变量:
 
$PKG_CONFIG_DIR                  = /home/xiewei/stuff/workspace/staging/armv7a-linux-gnueabi/usr/lib/pkgconfig
$PKG_CONFIG_PATH                 = /home/xiewei/stuff/workspace/staging/armv7a-linux-
gnueabi/usr/lib/pkgconfig:/home/xiewei/stuff/workspace/staging/armv7a-linux-gnueabi/usr/share/pkgconfig
$PKG_CONFIG_DISABLE_UNINSTALLED  = yes
$PKG_CONFIG_SYSROOT_DIR          = /home/xiewei/stuff/workspace/staging/armv7a-linux-gnueabi

以pkg-config --cflags glib-2.0为例,
pkg-config启动后,按照如下顺序来添加pc查找的目录:

 PKG_CONFIG_PATH -> PKG_CONFIG_LIBDIR -> PKG_CONFIG_PC_PATH 

其中,前两个在env中定义,PC_PATH在Makefile.am中定义,也就是说,在编译期就决定了的。
代码如下:

main.c +285
  search_path = getenv ("PKG_CONFIG_PATH");
  if (search_path)
    {
      add_search_dirs(search_path, G_SEARCHPATH_SEPARATOR_S);
    }
  if (getenv("PKG_CONFIG_LIBDIR") != NULL)
    {
      add_search_dirs(getenv("PKG_CONFIG_LIBDIR"), G_SEARCHPATH_SEPARATOR_S);
    }
  else
    {
      add_search_dirs(PKG_CONFIG_PC_PATH, G_SEARCHPATH_SEPARATOR_S);
    }
Makefile.am:INCLUDES=-DPKG_CONFIG_PC_PATH="\"$(pc_path)\"" $(included_glib_includes)
Makefile:
libdir = /home/xiewei/stuff/workspace/staging/i686-linux/usr/lib
datadir = /home/xiewei/stuff/workspace/staging/i686-linux/usr/share
pc_path = ${libdir}/pkgconfig:${datadir}/pkgconfig

然后pkg-config会先后扫描这些目录中的所有.pc文件,并把这些pc文件记录到一个包名(glib-2.0)和pc路径(全路径)映射的hash_table中,如果同一
个名称的pc在两个不同的目录找到,则pkg-config仅仅会记录第一个查找到的pc文件的路径,而忽略后面查找到的该包的pc。
hash_table定义如下,

pkg.c +247
package_init():
      packages = g_hash_table_new (g_str_hash, g_str_equal);  // package->key和package指针的对应
      locations = g_hash_table_new (g_str_hash, g_str_equal);  // pkgname和filename全称的对应(包括从/开始的路径和文件名称)
      path_positions = g_hash_table_new (g_str_hash, g_str_equal); // 该pkgname和查找目录列表中的第几个目录对应

对于glib-2.0.pc, pkg->key = "glibc-2.0", pkg->name = "GLib"
通过dent->d_name = "glibc-2.0.pc" 找到 pkgname = "glibc-2.0",
package->key正常情况下,和pkgname是一样的。


第一次查找到给出的debug信息:
File 'glib-2.0.pc' appears to be a .pc file
第二次查找到给出的debug信息:
File 'glib-2.0.pc' ignored, we already know about package 'glib-2.0'

有一点需要注意的是,如果环境变量中定义了PKG_CONFIG_SYSROOT_DIR,则会在返回-I及-L的后面先紧跟着这个SYSROOT,然后才是正常的/usr/include
等。

代码: pkg.c +466 string_list_to_string (GSList *list)
  if (pcsysrootdir != NULL && tmpstr[0] == '-' &&
     (tmpstr[1] == 'I' || tmpstr[1] == 'L'))
  {
      g_string_append_c (str, '-');
      g_string_append_c (str, tmpstr[1]);
      g_string_append (str, pcsysrootdir);
      g_string_append (str, tmpstr+2);
  }

 

阅读(1824) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~