将编译库链接到更新版本的glibc

时间:2013-02-18 06:50:03

标签: c shared-libraries glibc ftdi

我正在开发一个使用ftdi D2XX驱动程序与ENTTEC DMX usb pro设备连接的项目。存储在/ usr / local / lib /中的ftdi驱动程序(libftdi2xx.so.1.1.12)是针对glibc v2.14或更高版本编译的。

我正在开发debian 7,它只支持glibc v2.13。执行我编写的C代码(调用ftdi驱动程序)时,它会出错:

./a.out: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /usr/local/lib/libftd2xx.so)

这是有道理的,因为知道glibc版本是不兼容的。我已经下载并安装了最新版本的glibc(v2.17)到我的计算机上的临时目录('〜/ glibc-testing / install / lib /')并使用了这个调用:

~/glibc-testing/install/lib/ld-linux-x86-64.so.2 --library-path ~/glibc-testing/install/lib/ ./a.out 

通过此调用,我可以成功运行C代码。

我想将此C代码编译为共享库。它将用于与DMX设备连接,并将由C#开发的主应用程序调用。

我不确定如何前进。我需要做的是告诉fdti驱动程序始终使用较新的glibc,同时让应用程序的其余部分使用普通库。 ftdi 2DXX驱动程序仅可预编译(无源代码可用)。有没有办法将这个预编译的程序链接到新库?

我查看了导出LD_LIBRARY_PATH = / home /.../ glibc / install / lib /的选项,但收效甚微。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以在自己的代码中提供缺少的功能,但请注意这些功能是版本化的,您可以提供地图文件,也可以随代码一起执行所有操作。例如:

#define SYMVER(ver, sym) __asm__(".symver " #sym "," #sym "@" #ver "\n")

SYMVER(GLIBC_2.14, foo);
int foo(int a, char *b)
{
    return 4;
}

为了弄清楚要实施什么,你可以使用readelf:

readelf -s /usr/local/lib/libftd2xx.so | grep '@GLIBC_2\.14'

就功能而言,就是这样。

现在棘手的部分是让加载器相信它有正确的库(除非你想实现自己的加载器),因为你需要修补库以删除对GLIBC_2.14的引用,因为它将特别关注libc。

有几种方法可以继续;到目前为止,最简单的方法是将GLIBC_2.14替换为GLIBC_2.13,请记住,您需要使用替换版本(即GLIBC_2.13)来定义符号,因为版本是通过引用存储的。

你的程序应该运行。

现在,理论上你可以改为:

  • 解析ELF文件,在程序中找到DYNAMIC类型条目 标题,搜索VERNEED条目,最后跟随 那个你应该找到你可以修剪的要求表 引用(也可以使用.gnu.version_r部分标题 如果有的话可以到达那里。

  • 或者,您可以编写一个链接标准的加载程序 加载程序,但使用ptrace覆盖查找。

答案 1 :(得分:0)

其中一个变种是debian更新为sid。

另一种选择是更改文件/etc/ld.so.conf.d/libc.conf/etc/ld.so.conf.d/x86_64-linux-gnu.conf

这些文件包含在系统中搜索库的路径。

答案 2 :(得分:0)

您可以使用PatchELF修改提供的共享库的rpath:

$ patchelf --set-rpath /home/user/glibc-testing/install/lib/ libftdi2xx.so.1.1.12

然后使用:

编译您的共享库
$ gcc -Wl,-rpath=/home/user/glibc-testing/install/lib/ <rest of flags>

您编译的任何可执行文件都必须使用以下编译:

$ gcc -Wl,-rpath=/home/user/glibc-testing/install/lib/  -Wl,--dynamic-linker=/home/user/glibc-testing/install/lib/ld-linux-x86-64.so.2 <rest of flags>