Globalized TBB Environment Configuration on Linux

Last night I was chatting on the #tbb IRC channel with grad student who's experimenting with Threading Building Blocks. His platform is an Intel quad-core system running Fedora, and he was having a problem working with one of the TBB sample problems. We quickly realized that the user's environment was not properly configured for building programs using TBB, and so we investigated what had to be done.

Environment configuration may seem like a simple problem -- and of course it is. However, when someone comes to new software for the first time, the last thing they want is to find building or using the software to be not straightforward. Yes, the TBB documentation talks about configuring your environment, but if you haven't found the right document, or if you've only breezed through the documentation, then you may find yourself getting unexpected and unwanted errors when you try to do very basic things involving TBB (such as rebuilding or even running an example problem).

It's an annoyance to not be able to just open a terminal on a Linux system and immediately build a program when you've previously already installed all the required software, or run an already built program. So, in this post I'm going to describe the simple steps I took on my Gentoo Linux system, to eliminate these annoyances.

TBB "Getting Started Guide" instructions


Page 4 of the "Threading Building Blocks Getting Started Guide" has instructions on how to register environment variables on Linux and Mac OS systems. What you do is "source the tbbvars.[c]sh script". But this only sets up the environment in the shell you're currently using. And who wants to have to always do this every time you want to work with TBB?

Also, sourcing tbbvars.[c]sh in itself doesn't seem sufficient to enable you to build new TBB applications (or rebuild the example programs). The GCC compiler may not be able to find the TBB libraries you've built or installed on your system, resulting in an error when you attempt to rebuild an example problem that was already built by your initial TBB master build.

Finding the right tbbvars.[c]sh script


The first thing you need to do to "globalize" your TBB configuration is to find the TBB installation you want to use as your active version. If you downloaded the TBB source and built it by entering make, then you probably have only a single TBB installation on your system. However, if you downloaded a Linux-specific package (for example, tbb20_010oss_lin.tar.gz), then you will have multiple sets of prebuilt TBB versions on your system. This can be confusing when you execute something like locate tbbvars.sh, and see an unexpectedly large list of results. Which one's the "right" one?

The "right" one is the one that's in the directory that your execution of make created, or the one that's in the directory that matches your hardware, kernel, and the version of GCC you're using. Find that directory, and you've found the tbbvars.sh you need to work with. In my particular case, this directory happens to be

/home/kevin/Intel/tbb/tbb20_010oss_src/em64t/cc4.1.0_libc2.4_kernel2.6.16.21/bin

Globalizing TBB's configuration on Linux


If you look at the tbbvars.sh file, you see a bunch of environment settings related to TBB. The first two settings define the directory you just identified:

    • TBB20_INSTALL_DIR is the directory that was created when you unpacked your TBB download (/home/kevin/Intel/tbb/tbb20_010oss_src in my case).

    • TBB_ARCH_PLATFORM is the subdirectory that is related your hardware architecture and your Linux kernel and GCC software versions (in my case em64t/cc4.1.0_libc2.4_kernel2.6.16.21); this directory tree should be created automatically when you build TBB from source.



The first step in globalizing your TBB installation is to enter these variables into your .bashrc file (assuming you're running BASH). Here's how I did it for my system:

# tbb environment

TBB20_INSTALL_DIR='/home/kevin/Intel/tbb/tbb20_010oss_src'
TBB_ARCH_PLATFORM='emt64/cc4.1.0_libc2.4_kernel2.6.16.21'


Next in tbbvars.sh, there are settings that create additional environment variables or concatenate directories if the variables already exist. I simply copied this entire sequence into my .bashrc file, resulting in this completed "tbb environment" section:

# tbb environment

TBB20_INSTALL_DIR='/home/kevin/Intel/tbb/tbb20_010oss_src'
TBB_ARCH_PLATFORM='emt64/cc4.1.0_libc2.4_kernel2.6.16.21'
if [ -z "${LD_LIBRARY_PATH}" ]; then
LD_LIBRARY_PATH="${TBB20_INSTALL_DIR}/${TBB_ARCH_PLATFORM}/lib";
export LD_LIBRARY_PATH
else
LD_LIBRARY_PATH="${TBB20_INSTALL_DIR}/${TBB_ARCH_PLATFORM}/lib:$LD_LIBRARY_PATH";
export LD_LIBRARY_PATH
fi
if [ -z "${DYLD_LIBRARY_PATH}" ]; then
DYLD_LIBRARY_PATH="${TBB20_INSTALL_DIR}/${TBB_ARCH_PLATFORM}/lib";
export DYLD_LIBRARY_PATH
else
DYLD_LIBRARY_PATH="${TBB20_INSTALL_DIR}/${TBB_ARCH_PLATFORM}/lib:$DYLD_LIBRARY_PATH";
export DYLD_LIBRARY_PATH
fi
if [ -z "${CPATH}" ]; then
CPATH="${TBB20_INSTALL_DIR}/include"; export CPATH
else
CPATH="${TBB20_INSTALL_DIR}/include:$CPATH"; export CPATH
fi


With this in place, I was able to open a new terminal window, go to my built TBB examples, and immediately run them. However, when I tried to rebuild an example problem, I got an error message:

make
g++ -O2 -DNDEBUG -o sub_string_finder sub_string_finder.cpp -ltbb
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/../../../../x86_64-pc-linux-gnu/bin/ld:
cannot find -ltbb
collect2: ld returned 1 exit status
make: *** [release] Error 1

Helping GCC find the TBB libraries


This problem could have been solved a couple of different ways, but I chose to simply find the TBB library GCC was looking for and put it into one of the locations where GCC searches for libraries by default.

> su
Password:
localhost lib # pwd
/home/kevin/Intel/tbb/tbb20_010oss_src/em64t/cc3.2.3_libc2.3.2_kernel2.4.21/lib
localhost lib # cp -p * /usr/local/lib


After doing that, my build worked fine:

> make
g++ -O2 -DNDEBUG -o sub_string_finder sub_string_finder.cpp -ltbb
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/../../../../x86_64-pc-linux-gnu/bin/ld:
warning: libstdc++.so.5, needed by /usr/local/lib64/libtbb.so,
may conflict with libstdc++.so.6
g++ -O2 -DNDEBUG -o sub_string_finder_extended sub_string_finder_extended.cpp -ltbb
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/../../../../x86_64-pc-linux-gnu/bin/ld:
warning: libstdc++.so.5, needed by /usr/local/lib64/libtbb.so,
may conflict with libstdc++.so.6
g++ -O2 -DNDEBUG -o sub_string_finder_pretty sub_string_finder_pretty.cpp -ltbb
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/../../../../x86_64-pc-linux-gnu/bin/ld:
warning: libstdc++.so.5, needed by /usr/local/lib64/libtbb.so,
may conflict with libstdc++.so.6
./sub_string_finder_extended
Done building string.
Done with serial version.
Done with parallel version.
Done validating results.
Serial version ran in 12.0151 seconds
Parallel version ran in 5.74873 seconds
Resulting in a speedup of 2.09005
>

Conclusion


Configuring your Linux system for simplified everyday use of Threading Building Blocks is not a difficult task. But, for the uninitiated, knowing where to look and what to do can be a cause of frustration (witness the volume of questions on the TBB forum and elsewhere related to basic TBB install and configuration issues).

I'll investigate and document basic TBB configuration on other platforms TBB users are working with in future posts.

Kevin Farnham
O'Reilly Media
TBB Open Source Community

For more complete information about compiler optimizations, see our Optimization Notice.