Reputation: 77
I'm a student doing research involving extending the TM capabilities of gcc. My goal is to make changes to gcc source, build gcc from the modified source, and, use the new executable the same way I'd use my distro's vanilla gcc.
I built and installed gcc in a different location (not /usr/bin/gcc
), specifically because the modified gcc will be unstable, and because our project goal is to compare transactional programs compiled with the two different versions.
Our changes to gcc source impact both /gcc
and /libitm
. This means we are making a change to libitm.so, one of the shared libraries that get built.
My expectation:
myprogram.cpp
with /usr/bin/g++
, the version of libitm.so that will get linked should be the one that came with my distro;~/project/install-dir/bin/g++
, the version of libitm.so that will get linked should be the one that just got built when I built my modified gcc.But in reality it seems both native gcc and mine are using the same libitm, /usr/lib/x86_64-linux-gnu/libitm.so.1
.
I only have a rough grasp of gcc internals as they apply to our project, but this is my understanding:
./test: relocation error: ./test: symbol _ITM_S1RU4, version LIBITM_1.0 not defined in file libitm.so.1 with link time reference
readelf
shows me that /usr/lib/x86_64-linux-gnu/libitm.so.1
does not contain our new symbols while ~/project/install-dir/lib64/libitm.so.1
does; if I re-run my program after simply copying the latter libitm over the former (backing it up first, of course), it does not produce the relocation error anymore. But naturally this is not a permanent solution.So I want the gcc I built to use the shared libs that were built along with it when linking. And I don't want to have to tell it where they are every time - my feeling is that it should know where to look for them since I deliberately built it somewhere else to behave differently.
This sounds like the kind of problem any amateur gcc developer would have when trying to make a dev environment and still be able to use both versions of gcc, but I had difficulty finding similar questions. I am thinking this is a matter of lacking certain config options when I configure gcc before building it. What is the right configuration to do this?
My small understanding of the instructions for building and installing gcc led me to do the following:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
I only have those config options because they seemed like the ones closest related to "only building the parts I need" and "not overwriting native gcc", but I could be wrong. After the initial config step I just re-run make -j2
and make install
every time I change the code. All these steps do complete without errors, and they produce the ~/project/install-dir/bin/
folder, containing the gcc
and g++
which behave as described.
I use ~/project/install-dir/bin/g++ -fgnu-tm -o myprogram myprogram.cpp
to compile a transactional program, possibly with other options for programs with threads.
(I am using Xubuntu 16.04.3 (64 bit), within VirtualBox on Windows. The installed /usr/bin/gcc
is version 5.4.0. Our source at ~/project/source-dir/
is a modified version of 5.3.0.)
Upvotes: 1
Views: 925
Reputation: 2881
You’re running into build- versus run-time linking differences. When you build with -fgnu-tm
, the compiler knows where the library it needs is found, and it tells the linker where to find it; you can see this by adding -v
to your g++
command. However when you run the resulting program, the dynamic linker doesn’t know it should look somewhere special for the ITM library, so it uses the default library in /usr/lib/x86_64-linux-gnu
.
Things get even more confusing with ITM on Ubuntu because the library is installed system-wide, but the link script is installed in a GCC-private directory. This doesn’t happen with the default GCC build, so your own GCC build doesn’t do this, and you’ll see libitm.so
in ~/project/install-dir/lib64
.
To fix this at run-time, you need to tell the dynamic linker where to find the right library. You can do this either by setting LD_LIBRARY_PATH
(to /home/.../project/install-dir/lib64
), or by storing the path in the binary using -Wl,-rpath=/home/.../project/install-dir/lib64
when you build it.
Upvotes: 2