How can I use Boost::regex.hpp library in C++? - c++

I tried to use Boost library but I failed, see my code:
#include "listy.h"
#include <boost/regex.hpp>
using namespace boost;
ListyCheck::ListyCheck() {
}
ListyCheck::~ListyCheck() {
}
bool ListyCheck::isValidItem(std::string &__item) {
regex e("(\\d{4}[- ]){3}\\d{4}");
return regex_match(__item, e);
}
When I tried to compile it I get those messages:
/usr/include/boost/regex/v4/regex_match.hpp:50:
undefined reference to
`boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator,
std::allocator > >,
std::allocator,
std::allocator > > > >,
boost::regex_traits >
::match()'
/usr/include/boost/regex/v4/basic_regex.hpp:425:
undefined reference to
`boost::basic_regex >
::do_assign(char const*, char const*, unsigned int)'
/usr/include/boost/regex/v4/perl_matcher.hpp:366:
undefined reference to
`boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator,
std::allocator > >,
std::allocator,
std::allocator > > > >,
boost::regex_traits >
::construct_init(boost::basic_regex > >
const&,
boost::regex_constants::_match_flags)'
etc...

You need to link to libboost_regex. Add -lboost_regex to the compiler switch if you're using gcc.

Those are linker errors. The Boost regex library is not a header-only library like shared_ptr (for example) - you need to link against the .a or .lib or whatever binary library.

You have to link against boost_regex.

had similar issue.
the solution was to link via cmake with the command target link library:
target_link_libraries(boostGraph Boost::regex Boost::date_time Boost::system Boost::filesystem Boost::thread Boost::graph Boost::program_options)
using the syntax -lboost_regex as offered here did not work (at least not with cmake)
the root issue could have been different versions of libraries, which cause the issue and even though the compiler and the linker do find the regex lib.

Related

undefined reference to boost::filesystem::path_traits::convert

I am trying to compile a program using cmake, and am seeing the following linker error:
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so:
undefined reference to
boost::filesystem::path_traits::convert(wchar_t const*, wchar_t
const*, std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >&, std::codecvt<wchar_t, char, __mbstate_t>
const&)' /home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so:
undefined reference to
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry
const&, std::__cxx11::basic_string,
std::allocator >&)'
The linker command that ninja generated looks like this:
g++ -pthread -DBOOST_ALL_DYN_LINK
utility/test/CMakeFiles/utilityTest.dir/loadCSVTests.cpp.o
utility/test/CMakeFiles/utilityTest.dir/main.cpp.o
utility/test/CMakeFiles/utilityTest.dir/randomDeviceTests.cpp.o -o
utility/test/utilityTest -rdynamic
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
utility/lib/libutilityLib.a utility/testLib/libutilityTestLib.a
utility/lib/libutilityLib.a
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
-Wl,-rpath,/home/quant/bin/boost_1_61_0/stage/lib
As you can see, I am linking against boost_filesystem and boost_system, so it's not the same problem as referenced on this SO post (and the many others like it).
I am using boost 1.61, which I compiled with gcc 5.3 (the same compiler as the one I'm compiling my program with).
What am I doing wrong?
I had a similar issue, this could be because of a new ABI which is introduced from gcc 5.1.
https://github.com/openframeworks/openFrameworks/issues/4203
I fixed mine by adding "add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)" to CMakeLists.txt

Undefined reference errors from an unneeded library

I'm getting some "undefined reference" errors in ld and am at a loss as to what's causing them.
My makefile builds several executables using commands like this:
g++ -ogui_program1 -Lpath/to/MyLibs gui_program1.o -lMyUI -lMyBusinessLogic \
-lMyUtil -lboost_regex
g++ -ogui_program2 -Lpath/to/MyLibs gui_program2.o -lMyUI -lMyBusinessLogic \
-lMyUtil -lboost_regex
g++ -ocli_program1 -Lpath/to/MyLibs cli_program1.o -lMyUI -lMyBusinessLogic \
-lMyUtil -lboost_regex
g++ -ocli_program2 -Lpath/to/MyLibs cli_program2.o -lMyUI -lMyBusinessLogic \
-lMyUtil -lboost_regex
And so on. (Actually, there are quite a few more libraries than this, but this is the general idea.)
MyUI, MyBusinessLogic, and MyUtil are all dynamic libraries that I've already built. To make writing the makefile simpler, the same list of libraries is used for both GUI and command line programs, even though the command line programs don't need libMyUI.so.
One and only one of the command line programs is giving numerous errors about undefined references to Boost.Regex symbols when I try to link it, even though I'm linking -lboost_regex with every binary:
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher >, boost::regex_traits > >::construct_init(boost::basic_regex > > const&, boost::regex_constants::_match_flags)'
libMyBusinessLogic.so: undefined reference to `boost::cpp_regex_traits::toi(char const*&, char const*, int) const'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::match()'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::construct_init(boost::basic_regex > > const&, boost::regex_constants::_match_flags)'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher, std::allocator > >, std::allocator, std::allocator > > > >, boost::regex_traits > >::find()'
libMyBusinessLogic.so: undefined reference to `boost::basic_regex > >::do_assign(char const*, char const*, unsigned int)'
libMyBusinessLogic.so: undefined reference to `boost::re_detail::perl_matcher >, boost::regex_traits > >::match()'
Linking all other programs works fine. If I remove -lMyUI from the one command-line program, then it works fine, even though MyUI doesn't show up anywhere in the error list.
Why isn't ld finding Boost.Regex symbols, when I've added -lboost_regex to the end of the command? Why does removing a seemingly unrelated library fix it? Why do other programs link without any problems?
I've figured out at least most of the answer. Due to some sloppiness in my makefile rules, libMyUI.so was linked against boost_regex, but libMyBusinessLogic.so wasn't. I'm guessing that, as a result, linking MyUI caused boost_regex to get pulled in prematurely, before the linker knew all of the symbols that MyBusinessLogic would need from it.
As long as I'm consistent - either all of My*.so link with boost_regex, or none of them do - everything works. I'm not sure which of these solutions is most preferred, but at least I have a fix.

How to dynamically build and link boost::regex with hidden inlines?

As part of my (OSX) project, I am building boost::regex as a dynamic library. When I build and link without -fvisibility-inlines-hidden, everything works as expected.
To work around a bug in another external dependency, I need to turn this compiler switch on, however. Doing so results in lots of linker errors like this one
Undefined symbols for architecture x86_64:
"boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*,
std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<
char const*, std::string> > >, boost::regex_traits<char,
boost::cpp_regex_traits<char> > >::find()", referenced from:
bool boost::regex_search<__gnu_cxx::__normal_iterator<char const*,
std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<
char const*, std::string> > >, char, boost::regex_traits<char,
boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*,
std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>,
boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>,
std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*,
std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char,
boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags,
__gnu_cxx::__normal_iterator<char const*, std::string>) in Regex.o
when I try to link boost to my project (the file "Regex.o" is part of the boost dylib). As I understand Apple's documentation, limiting inline visibility should just cause every dynamic lib to get its own instance of the inlined function, but should never cause linker errors.
It seems there is a related compiler bug for virtual methods, but neither perl_matcher::find() nor regex_search() are virtual methods.
Any suggestions/ideas?
$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
It turns out that this is a compiler bug in clang 3.1. Boost declares the template inline member function perl_matcher<...>::find() (and others) as external; only the instance linked into the boost dylib is not marked as external. Because it is inline, clang 3.1 hides this instance from the dylib's export table with -fvisibility-inlines-hidden.
It seems that this bug is fixed in the current trunk of clang (3.2.x). Until then, defining BOOST_REGEX_NO_EXTERNAL_TEMPLATES works around this bug (if it is acceptable to possibly have multiple instances of these inline functions in your binary). Otherwise, patching boost::regex to explicitly export the symbols defined in boost/regex/v4/instances.hpp using __attribute__ ((visibility("default"))) when BOOST_REGEX_INSTANTIATE is defined should also do the job (see the #define template hack at the top of instances.hpp).

boost's regex won't compile

I am using boost 1.45.0 on Ubuntu with Code::Blocks as my IDE, and I can't get basic_regex.hpp to compile. I'm pretty sure I set up boost correctly, because I can compile programs using boost::format without any errors. But I'm getting this annoying error, and I don't know how to get rid of it.
The code that is provoking the error:
boost::regex e("\"http:\\\\/\\\\/localhostr.com\\\\/files\\\\/.+?\"");
Compiler output (GCC):
obj/Debug/main.o
In function `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)'
/home/neal/Documents/boost_1_45_0/boost/regex/v4/basic_regex.hpp|379|
undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'|
||=== Build finished: 1 errors, 0 warnings ===|
Did I miss a step when setting up boost, or should I downgrade to another version of boost?
This looks like a linker error. boost::regex is not a header only library so you need to pass -lboost_regex with correct -L/path/to/boost/lib to linker.
Boost::Regex has some code that lives in a separate library (libboost_regex.so). To link against it, add -lboost_regex to the GCC commandline you're using.
Depending on your install, that might be libboost_regex-mt.so. In that case, you'll need to use -lboost_regex-mt on your command line. (The MT stands for mutlithreaded.)
That's a linking error rather than a compiler error. You need to explicitly link against Boost's regex library.
g++ program.cpp -lboost_regex -L/path/to/boost/lib

Boost Regex throwing an error

I have the following error when I try to compile my code in g+ compiler using eclipse
In function `ZSt19__iterator_categoryIPKSsENSt15iterator_traitsIT_E17iterator_categoryERKS3_':
C:/Program Files (x86)/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algobase.h:(.text$_ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j[boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)]+0x22): undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
All I have done is this statement
boost::regex re("\s+"); along with the header #inlucde
Could you kindly tell me how to proceed ?
It appears that you're not linking to the correct library. Most Boost libraries are header-only, so you don't need to do anything about them at link time. Boost::regex, however, is one of the few that requires that you link with a library along with giving the compiler the proper headers.
After you fix that, you'll want to re-check the escape in your string -- right now your passing "\s", which shouldn't be allowed (at a guess, you probably want "\s+" instead).