从不同位置的源构建的 GCC 错误地使用与本机 GCC 相同的共享库
GCC built from source in different location is incorrectly using same shared libs as native GCC
我是一名学生,正在研究扩展 gcc 的 TM 功能。我的目标是更改 gcc 源代码,从修改后的源代码构建 gcc,然后像使用我的发行版的 vanilla gcc 一样使用新的可执行文件。
我在不同的位置构建并安装了gcc(不是/usr/bin/gcc
),具体是因为修改后的gcc会不稳定,而且因为我们的项目目标是比较使用两个不同版本编译的交易程序。
我们对 gcc 源代码的更改影响 /gcc
和 /libitm
。这意味着我们正在对 libitm.so 进行更改,这是已构建的共享库之一。
我的期望:
- 在使用
/usr/bin/g++
编译 myprogram.cpp
时,将 linked 的 libitm.so 版本应该是我的发行版附带的版本;
- 当用
~/project/install-dir/bin/g++
编译它时,linked 的 libitm.so 版本应该是我构建修改后的 gcc 时刚刚构建的版本。
但实际上 本地 gcc 和我的都使用相同的 libitm, /usr/lib/x86_64-linux-gnu/libitm.so.1
.
我对适用于我们项目的 gcc 内部原理只有粗略的了解,但这是我的理解:
- 我们的更改告诉一个编译器有条件地插入我们自己的 "function builtin" 而不是它通常使用的 "function builtin",这是/变成一个 "symbol" 需要 link 到 libitm .
- 当我使用新的 gcc 编译我的程序时,该过程检测到这些条件并成功插入符号,但是在 运行 时我的程序给出了一个 "relocation error" 指示符号不是在它正在搜索的文件中定义:
./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 使用在 linking 时与其一起构建的共享库。 而且我不想必须每次都告诉它它们在哪里 - 我的感觉是它应该知道在哪里寻找它们,因为我故意将它构建在其他地方以表现不同。
这听起来像是任何业余 gcc 开发人员在尝试制作开发环境并且仍然能够使用两个版本的 gcc 时都会遇到的问题,但我很难找到类似的问题。我认为这是在构建 gcc 之前配置 gcc 时缺少某些配置选项的问题。执行此操作的正确配置是什么?
我对 the instructions for building and installing gcc 的浅薄理解促使我做了以下事情:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
我只有那些配置选项,因为它们似乎与 "only building the parts I need" 和 "not overwriting native 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 的修改版本。)
您正在 运行 构建时间与 运行 时间 linking 差异。当您使用 -fgnu-tm
构建时,编译器知道在哪里可以找到它需要的库,并告诉 linker 在哪里可以找到它;您可以通过将 -v
添加到 g++
命令来查看。但是,当您 运行 结果程序时,动态 linker 不知道它应该在 ITM 库的某个特殊位置查找,因此它使用 /usr/lib/x86_64-linux-gnu
.[=19 中的默认库=]
Ubuntu 上的 ITM 让事情变得更加混乱,因为该库是在系统范围内安装的,但 link 脚本是安装在 GCC 私有目录中的。默认 GCC 构建不会发生这种情况,因此您自己的 GCC 构建不会执行此操作,您会在 ~/project/install-dir/lib64
.
中看到 libitm.so
要在 运行 时解决此问题,您需要告诉动态 linker 在哪里可以找到正确的库。您可以通过设置 LD_LIBRARY_PATH
(至 /home/.../project/install-dir/lib64
)或在构建时使用 -Wl,-rpath=/home/.../project/install-dir/lib64
将路径存储在二进制文件中来执行此操作。
我是一名学生,正在研究扩展 gcc 的 TM 功能。我的目标是更改 gcc 源代码,从修改后的源代码构建 gcc,然后像使用我的发行版的 vanilla gcc 一样使用新的可执行文件。
我在不同的位置构建并安装了gcc(不是/usr/bin/gcc
),具体是因为修改后的gcc会不稳定,而且因为我们的项目目标是比较使用两个不同版本编译的交易程序。
我们对 gcc 源代码的更改影响 /gcc
和 /libitm
。这意味着我们正在对 libitm.so 进行更改,这是已构建的共享库之一。
我的期望:
- 在使用
/usr/bin/g++
编译myprogram.cpp
时,将 linked 的 libitm.so 版本应该是我的发行版附带的版本; - 当用
~/project/install-dir/bin/g++
编译它时,linked 的 libitm.so 版本应该是我构建修改后的 gcc 时刚刚构建的版本。
但实际上 本地 gcc 和我的都使用相同的 libitm, /usr/lib/x86_64-linux-gnu/libitm.so.1
.
我对适用于我们项目的 gcc 内部原理只有粗略的了解,但这是我的理解:
- 我们的更改告诉一个编译器有条件地插入我们自己的 "function builtin" 而不是它通常使用的 "function builtin",这是/变成一个 "symbol" 需要 link 到 libitm .
- 当我使用新的 gcc 编译我的程序时,该过程检测到这些条件并成功插入符号,但是在 运行 时我的程序给出了一个 "relocation error" 指示符号不是在它正在搜索的文件中定义:
./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 使用在 linking 时与其一起构建的共享库。 而且我不想必须每次都告诉它它们在哪里 - 我的感觉是它应该知道在哪里寻找它们,因为我故意将它构建在其他地方以表现不同。
这听起来像是任何业余 gcc 开发人员在尝试制作开发环境并且仍然能够使用两个版本的 gcc 时都会遇到的问题,但我很难找到类似的问题。我认为这是在构建 gcc 之前配置 gcc 时缺少某些配置选项的问题。执行此操作的正确配置是什么?
我对 the instructions for building and installing gcc 的浅薄理解促使我做了以下事情:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
我只有那些配置选项,因为它们似乎与 "only building the parts I need" 和 "not overwriting native 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 的修改版本。)
您正在 运行 构建时间与 运行 时间 linking 差异。当您使用 -fgnu-tm
构建时,编译器知道在哪里可以找到它需要的库,并告诉 linker 在哪里可以找到它;您可以通过将 -v
添加到 g++
命令来查看。但是,当您 运行 结果程序时,动态 linker 不知道它应该在 ITM 库的某个特殊位置查找,因此它使用 /usr/lib/x86_64-linux-gnu
.[=19 中的默认库=]
Ubuntu 上的 ITM 让事情变得更加混乱,因为该库是在系统范围内安装的,但 link 脚本是安装在 GCC 私有目录中的。默认 GCC 构建不会发生这种情况,因此您自己的 GCC 构建不会执行此操作,您会在 ~/project/install-dir/lib64
.
libitm.so
要在 运行 时解决此问题,您需要告诉动态 linker 在哪里可以找到正确的库。您可以通过设置 LD_LIBRARY_PATH
(至 /home/.../project/install-dir/lib64
)或在构建时使用 -Wl,-rpath=/home/.../project/install-dir/lib64
将路径存储在二进制文件中来执行此操作。