【发布时间】:2018-04-14 00:54:07
【问题描述】:
我是一名学生,从事涉及扩展 gcc 的 TM 功能的研究。我的目标是更改 gcc 源代码,从修改后的源代码构建 gcc,并以与使用发行版的 vanilla gcc 相同的方式使用新的可执行文件。
我在不同的位置构建并安装了 gcc(不是/usr/bin/gcc),特别是因为修改后的 gcc 会不稳定,而且因为我们的项目目标是比较使用两种不同编译的事务程序版本。
我们对 gcc 源代码的更改会影响 /gcc 和 /libitm。这意味着我们正在对 libitm.so 进行更改,这是已构建的共享库之一。
我的期望:
- 在编译
myprogram.cpp和/usr/bin/g++时,将被链接的 libitm.so 版本应该是我的发行版附带的版本; - 当使用
~/project/install-dir/bin/g++编译它时,将被链接的 libitm.so 版本应该是我构建修改后的 gcc 时刚刚构建的版本。
但实际上似乎本地 gcc 和我的都使用相同的 libitm,/usr/lib/x86_64-linux-gnu/libitm.so.1。
我对 gcc 的内部结构只有粗略的了解,因为它们适用于我们的项目,但这是我的理解:
- 我们的更改告诉编译器通过有条件地插入我们自己的“内置函数”而不是它通常使用的函数,并且这是 / 成为需要链接到 libitm 的“符号”。
- 当我使用新的 gcc 编译我的程序时,通过检测这些条件并成功插入符号,但是在运行时我的程序给出了一个“重定位错误”,表明符号未在它正在搜索的文件中定义:
./test: relocation error: ./test: symbol _ITM_S1RU4, version LIBITM_1.0 not defined in file libitm.so.1 with link time reference -
readelf告诉我/usr/lib/x86_64-linux-gnu/libitm.so.1不包含我们的新符号,而~/project/install-dir/lib64/libitm.so.1包含;如果我在简单地将后者 libitm 复制到前者之后重新运行我的程序(当然,首先备份它),它不会再产生重定位错误。但这自然不是永久的解决方案。
所以我希望我构建的 gcc 在链接时使用与它一起构建的共享库。而且我不想每次都告诉它它们在哪里 - 我的感觉是它应该知道在哪里寻找它们,因为我故意在其他地方构建它以表现不同。
这听起来像是任何业余 gcc 开发人员在尝试创建开发环境并且仍然能够使用两个版本的 gcc 时都会遇到的问题,但我很难找到类似的问题。我认为这是在构建之前配置 gcc 时缺少某些配置选项的问题。执行此操作的正确配置是什么?
我对@987654321@ 的小小的了解导致我做了以下事情:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
我只有那些配置选项,因为它们似乎与“仅构建我需要的部分”和“不覆盖本机 gcc”最相关,但我可能错了。在初始配置步骤之后,我每次更改代码时都重新运行make -j2 和make install。所有这些步骤都没有错误地完成,它们会生成~/project/install-dir/bin/ 文件夹,其中包含gcc 和g++,它们的行为与描述的一样。
我使用~/project/install-dir/bin/g++ -fgnu-tm -o myprogram myprogram.cpp 编译事务程序,可能还有其他选项用于线程程序。
(我在 Windows 上的 VirtualBox 中使用 Xubuntu 16.04.3(64 位)。安装的 /usr/bin/gcc 是 5.4.0 版。我们在 ~/project/source-dir/ 的源是 5.3.0 的修改版本。)
【问题讨论】:
-
你是如何告诉链接器使用
~/project/install-dir/lib64/libitm.so.1的? -
@muru 我没有明确告诉链接器任何事情, 我的问题/问题的一部分是它 not 使用该文件(我希望它自动这样做)。我按照描述构建了 gcc,并用它来编译描述的测试程序。然后当重定位错误告诉我找不到符号时,我基本上使用
find / -name "libitm*"来找出任何libitm.so文件在哪里(/usr/lib中的那些是发行版附带的;~/project/install-dir/中的那些是来自我的构建)。 -
链接器不会自动拾取库。您必须使用
-L选项或LD_LIBRARY_PATH,或为ldconfig添加配置,在链接器使用它之前通知它该目录。 -
@muru 不是我刚刚构建的 gcc 的链接器部分吗?您是说它不会自动搜索靠近安装位置的某些相对路径,它只是使用该环境变量或
-L选项或ldconfig?我会对此进行更多研究。 -
抱歉,我把链接器和加载器混为一谈了。编译时,链接器必须通过
-L标志告诉 gcc 的位置。运行时错误将来自加载程序,必须在运行时使用ldconfig或LD_LIBRARY_PATH环境变量告知库位置,除非您静态链接该特定库。
标签: gcc shared-libraries