Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将编译的库链接到更新版本的glibc_C_Shared Libraries_Glibc_Ftdi - Fatal编程技术网

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

将编译的库链接到更新版本的glibc,c,shared-libraries,glibc,ftdi,C,Shared Libraries,Glibc,Ftdi,我正在从事一个使用ftdi D2XX驱动程序与ENTTEC DMX usb pro设备接口的项目。ftdi驱动程序(libftdi2xx.so.1.1.12存储在/usr/local/lib/)是根据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

我正在从事一个使用ftdi D2XX驱动程序与ENTTEC DMX usb pro设备接口的项目。ftdi驱动程序(libftdi2xx.so.1.1.12存储在/usr/local/lib/)是根据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/的选项,但几乎没有成功


谢谢大家!

它是将debian更新为sid的变体之一

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

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

您可以使用来修改提供的共享库的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/
您编译的任何可执行文件都必须使用以下工具进行编译:

$ 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>
$gcc-Wl,-rpath=/home/user/glibc testing/install/lib/-Wl,--dynamic linker=/home/user/glibc testing/install/lib/ld-linux-x86-64.so.2

您可以在自己的代码中提供缺少的函数,但请注意,这些函数是有版本控制的,您可以提供映射文件,也可以随代码一起执行所有操作。例如:

#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文件,在程序中找到
    动态
    类型条目 标题,搜索
    VERNEED
    条目,最后 你应该在需求表中找到你可以修改的地方 参考(也可以使用
    .gnu.version\r
    部分标题 如果可以的话,去那里)

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


唯一明智的做法是尝试与生成驱动程序的人进行沟通,并请求与较旧的glibc链接的版本。您是否尝试过使用LD_PRELOAD?我认为设置rpath应该可以做到这一点,请参见!为什么应用程序的其余部分使用较旧的glibc很重要?真是疯了。如果你不能让驱动程序与旧的glibc链接,那么就用新的glibc构建整个应用程序。无论如何,在运行时你都需要一个更新的驱动程序。除了Nikos的评论之外,我还特别要求提供一个符合Linux标准库(LSB)规范某些版本的驱动程序。对于供应商来说,分发不符合LSB的用户模式驱动程序确实没有什么好的理由。