分享

ld的-rpath与-rpath-link选项

 guitarhua 2012-02-11

ld的-rpath与-rpath-link选项  

2011-05-13 14:07:15|  分类: toolchain |  标签: |字号 订阅

rtspplayer这个程序在手机上运行的时候,要使用fbsink来作为video sink组件。这是使用了framebuffer的一个video sink组件。所以在代码中,很自然只需要在gst_element_factory_make的时候将xvimagesink换成fbsink就可以 了。但是程序在scratchbox中编译了之后,传到了手机上,运行却发生错误,报告说:

No such element ...... `fbsink'

奇 怪的是在手机上使用alp-gst-inspect|grep "fbsink"却能查到这个element。后来才知道,fbsink这个element存在于/opt/alp/lib /libalp_media.so文件中。而这个.so文件不在rtspplayer运行期动态链接库的查找范围之内,所以,fbsink创建就失败了。

如何让libalp_media.so这个文件存在于rtspplayer运行期的动态链接库的查找范围内呢?很简单,在编译的时候, 加上 -L/opt/alp/lib -lalp_media即可。也就是说,虽然代码没有显式的调用这个.so中的函数,但是我们在编译的时候手动将这个.so作为一种dependency 链接上,这样就OK了。但是,加上这样的内容后,编译发生错误:

gcc -Wall -g -o rtspplayer `pkg-config --cflags --libs gtk+-2.0` -I/usr/include/gstreamer-0.10 -L/opt/alp/lib -lGSTfusion -lalp_media main.c gstplay.c gstplay-marshal.c
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_audiomgr.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_gstaudiomgrsrc.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_gstaudiomgrsink.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_core.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_sysutils.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/scratchbox/compilers/arm-linux-gnueabi/bin/../lib/gcc/arm-none-linux-gnueabi/4.1.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: libalp_drm1.so, needed by /opt/alp/lib/libalp_media.so, not found (try using -rpath or -rpath-link)
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_fclose'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_message_get_message_ID'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_settings_open'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_message_unpack_start'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_log'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_settings_close'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_is_drm_file'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_settings_init'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_fseek'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_fopen_with_permission'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_settings_get'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_connection_register_disconnect_callback'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_message_unpack_end'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_channel_connect'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_connection_register_receive_callback'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_check_rights_info'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_message_unpack_int32'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_ftell'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_settings_value_clean'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_ipc_message_unpack_string'
/opt/alp/lib/libalp_media.so: undefined reference to `alp_drm_fread'
collect2: ld returned 1 exit status
make: *** [rtspplayer] Error 1

这个错误报告说找不到libalp_gstaudiomgrsrc.so等一堆so文件,这些so文件都位于/opt/alp/lib目录下,他们是libalp_media.so所需要的。换句话说,在libalp_media.so中还存在需要的动态链接库。

在 这种情况下,-rpath, -rpath-link这两个选项应运而生了。其实我们费这么大劲,无非就是要把libalp_media.so这个加入到rtspplayer的动态链 接库查找列表中去,形象一点来说,就是使用命令ldd ./rtspplayer的时候,能看到libalp_media.so这一行。

-rpath/-rpath- link其实都是ld的option,不是gcc的。gcc只是一个wrapper,将preprocessor, assemble, link三者结合了起来。-rpath <dir>的作用是手动将一个目录强行指定成一个.so文件的搜索目录,他的优先级在LD_LIBRARY_PATH和/etc /ld.so.conf...这些地方定义的.so文件搜索目录之上。由于这个目录是由程序的开发人员在编译的时候指定的,所以将来这个程序到了其他机器 上运行的时候,这个目录是不能修改的。

-rpath-link和-rpath类似,只不过-rpath-link <dir>指定的是该程序需要的某个动态链接库,如果还需要其他的动态链接库(就象我们这里libalp_media.so还需要其他 的.so一样)的时候,到哪个/哪些目录下去查找需要的.so。而且,和-rpath不同,在-rpath-link中定义的目录,有可能在ldd <exec>的输出中看不见,因为这里定义的目录不是该执行程序本身所需要的。

清楚了这两个option的含义之后, 来看用法,要在gcc的命令行中直接使用这两个option,必须遵循语法:-Wl,......。比 如:-Wl,--rpath-link /opt/alp/lib。-Wl就是告诉gcc,后面的内容是传递给linker的option。如果直接使用ld的话,就不需要-Wl,了。所以,上 面我们的编译命令就变成这样,就OK了:

gcc -Wall -g -o rtspplayer -Wl,--rpath-link /opt/alp/lib `pkg-config --cflags --libs gtk+-2.0` -I/usr/include/gstreamer-0.10 -L/opt/alp/lib -lGSTfusion -lalp_media main.c gstplay.c gstplay-marshal.c

这样,再次将生成的rtspplayer拷贝到手机中就可以运行了,不会再说找不到fbsink element了。

这里是gcc命令行中给assembler, preprocessor, linker传递option的具体关键字列表:
Code: Select all
  -Wa,<options>            Pass comma-separated <options> on to the assembler
  -Wp,<options>            Pass comma-separated <options> on to the preprocessor
  -Wl,<options>            Pass comma-separated <options> on to the linker



此外,定义LD_LIBRARY_PATH也是可以的。这样就不用加-Wl,--rpath-link /opt/alp/lib这个内容了。具体的ld是如何查找动态链接库的逻辑,请看man ld中有关-rpath, -rpath-link这两部分的详细解释。




-rpath=dir

Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime. The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when linking an ELF executable, the contents of the environment variable LD_RUN_PATH will be used if it is defined.


-rpath-link=dir

When using ELF or SunOS, one shared library may require another. This happens when an ld -shared link includes a shared library as one of the input files.

When the linker encounters such a dependency when doing a non-shared, non-relocatable link, it will automatically try to locate the required shared library and include it in the link, if it is not included explicitly. In such a case, the -rpath-link option specifies the first set of directories to search. The -rpath-link option may specify a sequence of directory names either by specifying a list of names separated by colons, or by appearing multiple times.



This option should be used with caution as it overrides the search path that may have been hard compiled into a shared library. In such a case it is possible to use unintentionally a different search path than the runtime linker would do.


The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多