Boost:;program_options 1.49 - can't link with -lboost_program_options - c++

I'm attempting my first use of Boost anything so I thought I'd start with program_options. I'm developing on a Raspberry Pi running Debian Wheezy. I started by "apt-get install libboost1.49-all" and everything seemed to install correctly. I can see .a and .so libraries in /usr/lib.
/usr/lib/libboost_program_options.a
/usr/lib/libboost_program_options-mt.a -> libboost_program_options.a
/usr/lib/libboost_program_options-mt.so -> libboost_program_options.so.1.49.0
/usr/lib/libboost_program_options.so -> libboost_program_options.so.1.49.0
/usr/lib/libboost_program_options.so.1.49.0
I can compile some example source I found here by using
g++ boost_program_options.cpp -c
but I cannot get anything to link. I've tried explicitly specifying the library path using no -l and got nothing but several pages of undefined reference errors. I tried another example code and got a compile problem that indicated to me that I wasn't using "g++ -std=c++0x" but that's not the problem either. I'm stuck. I've also tried
g++ -std=c++0x boostme.cpp -o boostme -L/usr/lib -lboost_program_options
I'm just banging my head against the wall at this point. Among the stackoverflow posts I've seen so far, I'm doing everything correctly. My head hurts. ;-)
Just some sample error messages below. Still poking around.
/tmp/ccTbmurt.o: In function `boost::program_options::error_with_option_name::~error_with_option_name()':
boostme.cpp:(.text._ZN5boost15program_options22error_with_option_nameD2Ev[_ZN5boost15program_options22error_with_option_nameD5Ev]+0x118): undefined reference to `vtable for boost::program_options::error_with_option_name'
/tmp/ccTbmurt.o: In function `boost::program_options::validation_error::validation_error(boost::program_options::validation_error::kind_t, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)':
boostme.cpp:(.text._ZN5boost15program_options16validation_errorC2ENS1_6kind_tERKSsS4_i[_ZN5boost15program_options16validation_errorC5ENS1_6kind_tERKSsS4_i]+0x30): undefined reference to `boost::program_options::validation_error::get_template(boost::program_options::validation_error::kind_t)'

Because the signature of that destructor really should be
~error_with_option_name() throw() {}
I'm going to look into my crystal ball and say that - maybe - somewhere you might have #define throw() or similar hidden in your codebase.
That, or you might have conflicting version of the header files in your include paths, which do not correspond to the version of the libraries found at link time

Related

Linking error in boost program_options

I'm trying to build a 3rd party C++ library from source, and it depends on Boost. In the very last step when building, I got errors like this:
[ 90%] Linking CXX executable Shannon_RNASeq_Cpp
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o: In function `command_line_for_find_rep(int, char**, Shannon_C_setting&,
std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >&, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&)':
/home/lambda/Shannon_Cpp_RNA_seq/src/main.cpp:320: undefined reference to `boost::program_options::options_description::options_description(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
I searched other questions on StackOverflow (e.g. Boost Program Options link error), and initially thought that it was caused by the different compilers used to build the non-header part of Boost, so I downloaded the source of Boost 1.68.0 and built it in my personal directory using the same compiler I used to build the 3rd party library (the compiler is gcc 8.2.0), and from the error message, I can tell that C++11 standard was used (you can see cxx11 in the error message), so it can't be the case that compiler not supporting C++11 is causing the trouble, as supposed previously (e.g. undefined reference to boost::program_options in xubuntu). To build Boost with a custom compiler (the default compiler of the server is terribly outdated), I followed the instructions here.
Some further search reveals that this is a linking problem. The 3rd party library must be built by CMake, and I followed the instruction in an answer to a previous question (How to link C++ program with Boost using CMake), by adding this line to CMakeLists.txt in the root directory of the 3rd party library:
target_link_libraries(Shannon_RNASeq_Cpp ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE})
However, the same problem persists. I checked the file CMakeCache.txt, and confirmed that the desired compiler is used and Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE points to the libboost_program_options.so in the directory where I put Boost 1.68.0 (the server has other older versions of Boost). I then used make VERBOSE=1 to check the bash commands invoked while building the library. The command doesn't sound wrong; the Boost program_options library has been linked; here's the command from make VERBOSE=1:
/usr/bin/cmake3 -E cmake_link_script CMakeFiles/Shannon_RNASeq_Cpp.dir/link.txt --verbose=1
It's referring to something in link.txt, and here's what I found there:
/home/lambda/mylibs/bin/c++ -g -rdynamic CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/run_tasks.cpp.o -o
Shannon_RNASeq_Cpp lib_shannon/libmulti_graph_handler.a
lib_shannon/libcontig_graph_handler.a lib_shannon/libprimary_lib.a
-lboost_program_options lib_shannon/libsparse_flow_handler.a
-lglpk lib_shannon/libseq_graph_handler.a -lpthread
-lboost_system -Wl,-Bstatic -lmetis -Wl,-Bdynamic -lboost_filesystem
-lboost_program_options
So yes, Boost program_options has been linked (-lboost_program_options). I wonder if this is something wrong with program_options, since all errors that occurred at this stage are from program_options; I also linked to 2 other Boost compiled libraries, namely filesystem and system, and they do not appear in any error message I saw here.
I solved this problem myself (see my answer below), but new to CMake (and my only experiences with C++ is Rcpp), I don't know why it worked. Can someone please explain why switching to a static library worked? Also, when CMake linked to the default version of Boost on the server, it also by default used the .sos rather than the .as, even though the .as are available. Is there any way to tell CMake to use the .as rather than the .sos? Are there other solutions?
What I did was to change all the .sos in CMakeCache.txt into .as, like I changed libboost_program_options.so into libboost_program_options.a, and this error went away. Then the command from make VERBOSE=1 became:
/home/lambda/mylibs/bin/c++ -g -rdynamic CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/run_tasks.cpp.o
-o Shannon_RNASeq_Cpp lib_shannon/libmulti_graph_handler.a
lib_shannon/libcontig_graph_handler.a lib_shannon/libprimary_lib.a
-Wl,-Bstatic -lboost_program_options lib_shannon/libsparse_flow_handler.a
-Wl,-Bdynamic -lglpk lib_shannon/libseq_graph_handler.a -lpthread
-Wl,-Bstatic -lboost_system -lmetis -lboost_filesystem -lboost_program_options -Wl,-Bdynamic

Compiling boost flags with explicit location on boost binaries

I am compiling a project that needs boost::filesystem. I have included the following flags in my compilation step:
g++ -Wall -ggdb -Werror -std=c++11 -lboost_system
-lboost_filesystem -I /custom/path/to/boost_1_67_0
-o build/main build/cp.o build/walk.o build/diff.o build/main.o
and I get an error:
build/cp.o: In function `boost::filesystem::relative(boost::filesystem::path const&, boost::filesystem::path const&)':
/custom/path/boost_1_67_0/boost/filesystem/operations.hpp:690: undefined reference to `boost::filesystem::detail::relative(boost::filesystem::path const&, boost::filesystem::path const&, boost::system::error_code*)'
build/cp.o: In function `boost::filesystem::weakly_canonical(boost::filesystem::path const&)':
/custom/path/boost_1_67_0/boost/filesystem/operations.hpp:728: undefined reference to `boost::filesystem::detail::weakly_canonical(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status
make: *** [build] Error 1
I suspect that this is due to the fact that I have various other boost::filesystem binaries, some of which don't have relative and weakly_canonical in their versions. I don't really know where to supply the argument to specify the location of the binaries either. I suspect it's something to do with the flags lboost_system and lboost_filesystem where I can supply the location.
I am currently in process of building the .so's but I can see that the filesystem .so is already successfully built at /custom/path/boost_1_67_0/bin.v2/libs/filesystem/build/gcc-4.8.5/release/threading-multi/libboost_filesystem.so.1.67.0, so I want to point to that in the mean time. Building the library is taking a really long time.
So is it the -lboost_{libname} flags that I can extend upon? Is it the -I flag?
EDIT: Now that the binary location specified by --prefix during build is done, I tried the same thing, even with -L and it didn't work. Refer to my answer below for the LD_LIBRARY_PATH solution.
I have a solution, but it's not pretty:
I suspect it's because the other boost library binary is specified in $LD_LIBRARY_PATH, I could not load my own library in precedence using -L /custom/path/....
Thus, I did:
export LD_LIBRARY_PATH=/custom/path/...:$LD_LIBRARY_PATH
And it works.
This is by no means a good answer because it doesn't really make this build process portable to users without the LD_LIBRARY_PATH flag. Better answers will be approved instead of this.
Looks like you still need to provide the -L GCC option.
Use -L to tell the compiler where to look for the boost libraries.
Also, make sure you used bjam/b2 to install boost in a proper place. That bin.v2 directory is used to build boost libraries and not install.

Can't get googletest running with ubuntu (linker errors)

I've built googletest using make under linux, the resulting files are libgtest.a libgtest_main.a.
I referenced the include files from my application and added the following lib dependencies (in the given order):
-lgtest
-lpthread
However I get the following two linker errors when I try to compile:
more undefined references to `testing::internal::EqFailure(char const*, char const*, testing::internal::String const&, testing::internal::String const&, bool)
undefined reference to `testing::internal::String::ShowCStringQuoted(char const*)
From what I've seen within the googletest source, the EqFailure function is directly implemented within gtest.cc. I don't understand why I should get a linker error here, the other definitions from googletest could obviously also be found (if I remove -lgtest, I get alot of more linker errors).
What am I missing? Thank you in advance.
Make sure you do not accidentally mix your own gtest and the one shipped with ubuntu.
I use cmake to build and got the same errors due to cmake opting for /usr/include over my own custom built version (which is what I linked with).

Linking errors on Linux gcc 4.3.4: "undefined reference" related to "jpeg" library (e.g., undefined reference to `jpeg_std_error(jpeg_error_mgr*)')

I am working with a large C++ code that has been developed over a few years. I have added to the code and have been successfully running it on Mac OX 10.7.5. However, it is very slow and I now want to run it on a cluster (g++ (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973]). I am not very experienced as far as C++ and I'm a complete newbie as far as dealing with compilation / linking.
I am unable to get past a linking error related to a "jpeg" library and would be very grateful for any help. I have the library code installed in a directory where my code resides, but my understanding is that it is also available from the compiler.
There is a lot of error output, so I won't post it all. Here is the first part:
/data/place/number/account/program/libraries/libfile_intel.a(Grid.o):
In function program::Grid<double>::SaveToJPG(char const*,
int, bool, bool) const':
Grid.cpp:(.text._ZNK3program20GridIdE9SaveToJPGEPKcibb[program::Grid<double>::SaveToJPG(char
const*, int, bool, bool) const]+0x499): undefined reference to
jpeg_std_error(jpeg_error_mgr*)'
Grid.cpp:(.text._ZNK3program20GridIdE9SaveToJPGEPKcibb[program::Grid::SaveToJPG(char
const*, int, bool, bool) const]+0x4b5): undefined reference to
`jpeg_CreateCompress(jpeg_compress_struct*, int, unsigned long)'
What I have tried:
When I did a search in Google on this problem, I discovered from an old forum post that the jpeg library compiles in C. This apparently causes the C++ compiler to mess up names. I'm not clear on what this means, but I followed advice to add:
extern "C" {
#include "jpeglib.h"
}
in all of the files in my jpeg directory that contain "#include "jpeglib.h." I wrote, "jpeglib.h" because, as I mentioned, I have a directory containing the jpeg code. However, I did also try to use the jpeg code provided by default and I got a message saying it is not available on the cluster compiler.
In my makefile, I have checked all of my includes and paths. These do not seem to be the problem. Also, I have similar paths and includes for other libraries in other directories, and they're fine.
I also added: -lstdc++ to my list of compiler options (from advice on another old forum post). It had zero effect.
One weird observation I have made is that when I do "make" of the entire code (several libraries within various directories), the jpeg library does not make unless I specifically go into its directory and do "make" there. As I said, the code is way too big to post this to demonstrate that I have no path errors. I am pretty sure I don't, but this behavior seems very odd.
If anyone is still with me after this long post, I would be very grateful for any tips. Thanks.
Edit:
In my makefile, here is what i have for compiling/linking:
CC = g++
OPTIONS = -O3 -fpermissive -w -DSAMG_UNIX_LINUX -DSAMG_LCASE_USCORE
-DNDEBUG -DCSP_WITH_SAMG_SOLVER
Edit 2: result of Svens's advice
I did:
find /usr /opt -iname libjpeg*so*
And got:
/usr/lib/libjpeg.so.62
/usr/lib/libjpeg.so.62.0.0
/usr/lib64/libjpeg.so.62
/usr/lib64/libjpeg.so.62.0.0
/usr/lib64/libjpeg.so find:
/usr/lib64/mozilla': Permission denied find:
/usr/lpp/mmfs/gui/runtime': Permission denied
me#login1:/data/place/number/account/program/support_libraries/jpeg>
cd ../../libraries/
me#login1:/data/place/number/account/program/libraries> find $HOME
-iname libjpeg*so*
If my understanding is correct, the library exists and has been found in the "libraries" directory, which is where I expect. My main makefile that links all the libraries has an include path to the directory where the jpeg library resides. The other libraries in that directory are found. What is the "permission denied" doing?
Edit 3: result of Sven's advice to change the makefile options:
Here's what I changed:
First added "-lgems3k -L/usr/lib -ljpeg" to my LIBS (the libraries). This leads to the errors below.
Then added (leads to same error as original):
OPTIONS = -O3 -fpermissive -w -DSAMG_UNIX_LINUX -DSAMG_LCASE_USCORE -DNDEBUG -DCSP_WITH_SAMG_SOLVER -/usr/lib/libjpeg.so.62
-L/usr/lib -ljpeg /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld:
skipping incompatible /usr/lib/libm.so when searching for -lm
/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld:
skipping incompatible /usr/lib/libm.a when searching for -lm
/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld:
skipping incompatible /usr/lib/libc.so when searching for -lc
/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld:
skipping incompatible /usr/lib/libc.a when searching for -lc
/data/place/number/account/program/libraries/lib1_intel.a(Grid.o): In
function `program::Grid::SaveToJPG(char const*, int, bool,
bool) const':
Grid.cpp:(.text._ZNK3program20GridIdE9SaveToJPGEPKcibb[program::Grid::SaveToJPG(char
const*, int, bool, bool) const]+0x499): undefined reference to
`jpeg_std_error(jpeg_error_mgr*)'
and so on...
Following up on the comments: are you sure you installed libjpeg? Run
find $HOME -iname libjpeg\*so\*
to find the libjpeg you need to link to. This command will most likely yield several results.
You can simply take the first line of this output and append it to your compilation command, but leave out the "-ljpeg" suggested above.
If it does not give any output at all, you don't have libjpeg installed in your home. So either
install libjpeg
disable the part of the code that needs it if you don't need it either
extend your search,
like
find /usr /opt -iname libjpeg\*so\*
... and try with one of the libjpeg installations on the system.
EDIT (after libjpeg was found on the system):
Try appending
/usr/lib/libjpeg.so.62
to the compile command (the OPTIONS variable in your Makefile). If that doesn't work, try
-L/usr/lib -ljpeg
(Edit by Mats:)
Also make sure EVERY place where #include "jpeglib.h" is covered by extern "C" { ... }. It may make sense to replace these with a c++ wrapper include, which does the addition of extern "C" { ... } in one place, and then just include "wrapped_jpeglib.h" in the relevant places.
(End Edit by Mats)

linking to boost regex in gcc

i am trying to compile my program which uses regex on linux. I built the boost library in the
libs/regex/build
by typing
make -fgcc.mak
which created a directory gcc which contains the following four files
boost_regex-gcc-1_35
boost_regex-gcc-d-1_35
libboost_regex-gcc-1_35.a
libboost_regex-gcc-d-1_35.a
Now I want to use regex from my program which is in some arbitrary directory.
I #included boost/regex.hpp
I got the error which stated that regex.hpp is not found. Then I gave the -I option in the g++ compiler. I didn't get that error.
But I get the following error
undefined reference to `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)'
I googled and found that I need to somehow link one of the above 4 libraries to my program. How can I do it. Which one should I link and why?
Either add libboost_regex-gcc-1_35.a to your list of object files in your link step or add -static -lboost_regex-gcc-1_35 to the same. Also be sure that you have an -I switch pointing to your boost includes directory in your compile step. If the libraries are outside the typical search path (/usr/lib on *nix), add that directory to your link command with -Wl,-L/path/to/boost/libs for g++ or simply -L/path/to/boost/libs on ld.
I also faced similar problems when using boost filesystem. Here's what I needed to do to get it to link statically.
Excerpt from My Original (problematic) Makefile:
LIBS = -static -lboost_filesystem
Solution:
LIBS = -Wl,-Bstatic -lboost_filesystem -lboost_system -Wl,-Bdynamic
You can view the complete Makefile from
http://code.google.com/p/neptuner/source/browse/codebase/trunk/stratego/uboat/Makefile
Needed to add boost_system to make it link properly. Direct addition/specification of libboost*.a created more problems. Note the -Bdynamic is present to prevent static link of standard libraries.