Please bear with me. I really want to know as I am curious about the answer:
Is there an intelligent way to know the name of the library to link to at compile time?
Allow me to give you an example that illustrates perfectly the reason for my question.
I am a C++ newbie. I am learning about compiling, linking and libraries like boost. I just discovered boost/filesystem and wanted to try it. Having had troubles compiling, I used the following minimalist code:
// file boost_example.cpp
#include "boost/filesystem.hpp"
#include <iostream>
int main()
{
std::cout<<"Hello";
return 0;
}
I tried to compile it, but being a newbie, I made a newbie mistake: I forgot to link to the proper library! g++ boost_example.cpp -o run
To be precise, I experienced the problem explained in this chapter of this fine book.
I knew I had boost installed (I was told to install it to compile another project). I tried to copy from the Makefile of that other project, but the following didn't work: g++ boost_example.cpp -o run -lbooster
Trying to make an educated guess from the #include line in the code, I tried the following to no avail:
g++ boost_example.cpp -o run -lboost
By that time, I had started to search the web frantically. I hate search engines because most of the time, you don't find what you're looking. I found the following but they didn't help but to waste my time: g++ boost_example.cpp -o run -lboost_filesystem
Boost library link problem under kubuntu
C++/Boost linker errors
Since I am a RTFM kind of guy, I had actually checked the official documentation for the library I wanted to use: http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm but I didn't find any compile information.
At some stage, I got inspired to check what I had actually installed on my system:
Thus, I found the proper name of the library to link. The following worked:
$ locate boost_file
/usr/lib/libboost_filesystem-mt.a
/usr/lib/libboost_filesystem-mt.so
/usr/lib/libboost_filesystem-mt.so.1.38.0
g++ boost_example.cpp -o run -lboost_filesystem-mt
Now, beside using (possibly) intelligent guess work and searching the web, is there a more intelligent way to find the name of the library to link to? I would never have guessed the library name boost_filesystem-mt
given the header "boost/filesystem.hpp"
.
What's worse: boost_filesystem-mt is not mentioned anywhere on the official site! (I'm guessing it's distro/packaging dependent).
Again, I always make a point of RTFM before asking a question, and I found this chapter of the aforementioned book, so I checked what I could find on my system at /usr/lib/:
$ ls /usr/lib/boost
/usr/lib/libboost_date_time-mt.a /usr/lib/libboost_prg_exec_monitor-mt.so.1.38.0
/usr/lib/libboost_date_time-mt.so /usr/lib/libboost_program_options-mt.a
/usr/lib/libboost_date_time-mt.so.1.38.0 /usr/lib/libboost_program_options-mt.so
/usr/lib/libbooster.a /usr/lib/libboost_program_options-mt.so.1.38.0
/usr/lib/libbooster.so /usr/lib/libboost_python-mt.a
/usr/lib/libbooster.so.0 /usr/lib/libboost_python-mt-py25.a
/usr/lib/libbooster.so.0.0.0 /usr/lib/libboost_python-mt-py25.so
/usr/lib/libboost_filesystem-mt.a /usr/lib/libboost_python-mt-py25.so.1.38.0
/usr/lib/libboost_filesystem-mt.so /usr/lib/libboost_python-mt-py26.a
/usr/lib/libboost_filesystem-mt.so.1.38.0 /usr/lib/libboost_python-mt-py26.so
/usr/lib/libboost_graph-mt.a /usr/lib/libboost_python-mt-py26.so.1.38.0
/usr/lib/libboost_graph-mt.so /usr/lib/libboost_python-mt.so
/usr/lib/libboost_graph-mt.so.1.38.0 /usr/lib/libboost_regex-mt.a
/usr/lib/libboost_iostreams-mt.a /usr/lib/libboost_regex-mt.so
/usr/lib/libboost_iostreams-mt.so /usr/lib/libboost_regex-mt.so.1.38.0
/usr/lib/libboost_iostreams-mt.so.1.38.0 /usr/lib/libboost_serialization-mt.a
/usr/lib/libboost_math_c99f-mt.a /usr/lib/libboost_serialization-mt.so
/usr/lib/libboost_math_c99f-mt.so /usr/lib/libboost_serialization-mt.so.1.38.0
/usr/lib/libboost_math_c99f-mt.so.1.38.0 /usr/lib/libboost_signals-mt.a
/usr/lib/libboost_math_c99l-mt.a /usr/lib/libboost_signals-mt.so
/usr/lib/libboost_math_c99l-mt.so /usr/lib/libboost_signals-mt.so.1.38.0
/usr/lib/libboost_math_c99l-mt.so.1.38.0 /usr/lib/libboost_system-mt.a
/usr/lib/libboost_math_c99-mt.a /usr/lib/libboost_system-mt.so
/usr/lib/libboost_math_c99-mt.so /usr/lib/libboost_system-mt.so.1.38.0
/usr/lib/libboost_math_c99-mt.so.1.38.0 /usr/lib/libboost_thread-mt.a
/usr/lib/libboost_math_tr1f-mt.a /usr/lib/libboost_thread-mt.so
/usr/lib/libboost_math_tr1f-mt.so /usr/lib/libboost_thread-mt.so.1.38.0
/usr/lib/libboost_math_tr1f-mt.so.1.38.0 /usr/lib/libboost_unit_test_framework-mt.a
/usr/lib/libboost_math_tr1l-mt.a /usr/lib/libboost_unit_test_framework-mt.so
/usr/lib/libboost_math_tr1l-mt.so /usr/lib/libboost_unit_test_framework-mt.so.1.38.0
/usr/lib/libboost_math_tr1l-mt.so.1.38.0 /usr/lib/libboost_wave-mt.a
/usr/lib/libboost_math_tr1-mt.a /usr/lib/libboost_wave-mt.so
/usr/lib/libboost_math_tr1-mt.so /usr/lib/libboost_wave-mt.so.1.38.0
/usr/lib/libboost_math_tr1-mt.so.1.38.0 /usr/lib/libboost_wserialization-mt.a
/usr/lib/libboost_prg_exec_monitor-mt.a /usr/lib/libboost_wserialization-mt.so
/usr/lib/libboost_prg_exec_monitor-mt.so /usr/lib/libboost_wserialization-mt.so.1.38.0
And now I am scratching my head very hard, because I really don't know how to correlate the above to the list of boost libraries.
I apologize for this long-winded example, but it perfectly illustrate my problem:
Beside guesswork, searching the web, asking other people, trial and error, etc... is there a more intelligent way to find the name of the library one should link to? Aren't those kind of things supposed to be documented somewhere?
I'm certainly interested in knowing the answer as far as boost is concerned, but my question is more generic and is applicable to any library.
Incidentally, I have a very similar question regarding the name of linux packages (be they .deb or .rpm). If I am told that to compile such or such software I need, say, PRCE or FooBar, how do I know precisely the name of the package to install? I know how to user apt-cache (for Kubuntu debs) but some package naming are not intuitive and I often end up installing packages I don't really need...
Dynamic linking is the most common method, especially on Linux systems. Dynamic linking keeps libraries modular, so just one library can be shared between any number of applications. Modularity also allows a shared library to be updated independently of the applications that rely upon it.
The Filesystem Hierarchy Standard describes the filesystem conventions of a Linux system. In this standard, folders /lib, /usr/lib and /usr/local/lib are the default folders to store shared libraries.
Shared libraries are the most common way to manage dependencies on Linux systems. These shared resources are loaded into memory before the application starts, and when several processes require the same library, it will be loaded only once on the system. This feature saves on memory usage by the application.
There is a brute-force method I sometimes use, but you do have to know what directories to look in for the library you need (/lib, /usr/lib and /usr/local/lib are the usual suspects). I've created a shell script I call "gnm," (short for "grep nm," the two utilities it uses) with the below contents. If you create such a text file, remember to make it executable (chmod +x gnm).
#!/bin/sh
if [ $# -lt 2 ] ; then
echo Usage: $0 pattern file[s]
exit
fi
pattern=$1
shift
while [ $# -gt 0 ] ; do
nm $1 | grep $pattern > /dev/null
if [ $? -eq 0 ] ; then
echo $1
fi
shift
done
When I'm searching for a library that defines a particular symbol, I issue a command something like:
gnm symbol /usr/lib/*.a
For example, the source you mentioned gives me the following link errors:
boost_example.cpp:(.text+0x38): undefined reference to `boost::system::get_system_category()'
boost_example.cpp:(.text+0x44): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x50): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x5c): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x68): undefined reference to `boost::system::get_system_category()'
so I use the command:
gnm get_system_category /usr/lib/*.a
which reports:
/usr/lib/libboost_filesystem.a
/usr/lib/libboost_system.a
Trying the first of these results in the same errors, but the second one works:
g++ boost_example.cpp -lboost_system -o run
I don't know why I needed the system library where you needed filesystem; maybe different versions of Boost.
I just found the most intelligent and most official way (on my system) to figure out the link flag. What follows is only valid for boost on a Debian or Debian derivative distribution (like Kubuntu in my case). The other replies might be more generic for any library on any system.
Depending on the boost version installed, you may have the following file on your Debian-like distribution:/usr/share/doc/libboost1.38-doc/README.Debian
part of which reads:
-------- The following table shows which components use a library (shared or static) and the corresponding "-l" flag. Note that only the multithreaded version of the libraries is shipped. Component Link Flag Library Type --------- --------- ------------ Boost.Date_Time -lboost_date_time-mt static shared Boost.Filesystem -lboost_filesystem-mt static shared Boost.Graph -lboost_graph-mt static shared Boost.IOStreams -lboost_iostreams-mt static shared Boost.Math -lboost_math_c99-mt static shared -lboost_math_c99f-mt static shared -lboost_math_c99l-mt static shared Boost.MPI -lboost_mpi-mt static shared Boost.Program_options -lboost_program_options-mt static shared Boost.Python -lboost_python-mt-py24 static shared -lboost_python-mt-py25 static shared Boost.Regex -lboost_regex-mt static shared Boost.Serialization -lboost_serialization-mt static shared -lboost_wserialization-mt static shared Boost.Signals -lboost_signals-mt static shared Boost.System -lboost_system-mt static shared Boost.Test -lboost_prg_exec_monitor-mt static shared -lboost_unit_test_framework-mt static shared Boost.Thread -lboost_thread-mt static shared Boost.Wave -lboost_wave-mt static shared
One only had to find the proper place for the documentation!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With