Genivia / ugrep

NEW ugrep 6.5: a more powerful, ultra fast, user-friendly, compatible grep. Includes a TUI, Google-like Boolean search with AND/OR/NOT, fuzzy search, hexdumps, searches (nested) archives (zip, 7z, tar, pax, cpio), compressed files (gz, Z, bz2, lzma, xz, lz4, zstd, brotli), pdfs, docs, and more
https://ugrep.com
BSD 3-Clause "New" or "Revised" License
2.56k stars 109 forks source link

Unresolved boost_regex symbol #372

Closed drok closed 5 months ago

drok commented 5 months ago

When compiling on Ubuntu Xenial with boost-regex, the following link error occurs:

g++-8 -std=gnu++11      -pthread  -O2   -o ugrep ugrep-ugrep.o ugrep-cnf.o ugrep-glob.o ugrep-output.o ugrep-query.o ugrep-screen.o ugrep-stats.o ugrep-vkey.o ugrep-zopen.o -lpthread libreflex.a  -lbrotlidec -lzstd -llz4 -llzma -lz  libviiz.a -lbz2 -lboost_regex
ugrep-ugrep.o: In function `char const* boost::re_detail::re_is_set_member<char const*, char, boost::regex_traits<char, boost::cpp_regex_traits<char> >, unsigned int>(char const*, char const*, boost::re_detail::re_set_long<unsigned int> const*, boost::re_detail::regex_data<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, bool)':
ugrep.cpp:(.text._ZN5boost9re_detail16re_is_set_memberIPKccNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_S8_S8_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb[_ZN5boost9re_detail16re_is_set_memberIPKccNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_S8_S8_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb]+0x214): undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform[abi:cxx11](char const*, char const*) const'
ugrep.cpp:(.text._ZN5boost9re_detail16re_is_set_memberIPKccNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_S8_S8_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb[_ZN5boost9re_detail16re_is_set_memberIPKccNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEjEET_S8_S8_PKNS0_11re_set_longIT2_EERKNS0_10regex_dataIT0_T1_EEb]+0x361): undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform_primary[abi:cxx11](char const*, char const*) const'
collect2: error: ld returned 1 exit status

It seems related to abi:cxx11.

I had previously noted in commit 6978c50 that this problem occurs, thinking it was a problem introduced with that commit.

I have now verified it was a pre-existing condition, and thus that commit is complete. I will rewrite the commit to remove the WIP note, and I'm creating this issue in case you want to investigate the corner case; There is no more work I plan on doing on this front.

It can be reproduced on Ubuntu Xenial:

genivia-inc commented 5 months ago

This is not new to me and solutions exist to avoid this problem.

The boost_regex-mt.so lib stands for MT (multithread) safe. Some of the Boost libraries are MT safe regardless, but anyway this is a naming convention to make sure that MT safe Boost libraries are linked with applications that require MT safety. Because ugrep is multi-threaded, it makes sense to only link the -mt versions of Boost regex. If an -mt version is not available, then the ugrep build should fail. Install Boost regex properly or ensure to have PCRE2 instead (strongly preferred over Boost regex). It is annoying when Boost does not install the -mt version, even if the specific library is already MT safe. It's not correct IMHO, because old legacy Boost versions may not be MT safe initially and might still end up being linked if not for the -mt naming.

See also:

https://www.boost.org/doc/libs/1_84_0/libs/regex/doc/html/boost_regex/install.html which should also install the -mt library version https://stackoverflow.com/questions/2293962/boost-libraries-in-multithreading-aware-mode

drok commented 5 months ago

The first link you cite does not mention multi-threading at all - how is it relevant?

The second link, includes the following insight:

On Linux, by default in 1.42, you get no suffix. The reason you get no suffix on Linux is that pretty much no other library uses such convention, and it's much less important on Linux anyway.

Have you read the references you gave?

genivia-inc commented 5 months ago

And that is why it won't compile in the first place. That's what it says.

genivia-inc commented 5 months ago

For reference, without -mt was also a problem with ugrep in the past: see e.g. #67 #121 Best not to use Boost regex. It's not required and PCRE2 is way better.

genivia-inc commented 5 months ago

See also https://access.redhat.com/solutions/5750101#:~:text=Boost%20libraries%20with%20%2Dmt%20in,by%20the%20absence%20of%20%2Dmt%20.

drok commented 5 months ago

This is not solved, not even understood. It's not related to past issues where the boost library was not found. The paywall link is useless.

genivia-inc commented 5 months ago

Your build step shows -lboost_regex which is also mentioned in the other issues, no?

I don't know why your setup shows missing symbols, but -lboost_regex should be `-lboost_regex-mt. The MT version is the one we want. I know, many Boost libraries are MT safe without -mt. But if there is no -mt lib, then we should just skip it. If PCRE2 or Boost Regex are not installed, then configure should continue regardless. It means that option -P is not available. I've the logic in ugrep in place for that.

You can also specify a path, for example:

$ ./configure --disable-pcre2 --with-boost-regex=/opt/homebrew/Cellar/boost/1.83.0

where

/opt/homebrew/Cellar/boost/1.83.0/lib/libboost_regex-mt.dylib
/opt/homebrew/Cellar/boost/1.83.0/include/boost/regex.h

Also, ugrep does not require Boost Regex as a dependency. It runs fine without PCRE2 or Boost, with the only limitation that option -P is not available.

I noticed a typo in m4/ax_boost_regex.m4 where it should be LDFLAGS="$LDFLAGS -L${BOOST_REGEX_HOME}/lib" and not CPPFLAGS="$LDFLAGS -L${BOOST_REGEX_HOME}/lib". The patch for m4/ax_boost_regex.m4:

    if test "x$want_boost" = "xyes"; then
        BOOST_REGEX_OLD_LDFLAGS=$LDFLAGS
        BOOST_REGEX_OLD_CPPFLAGS=$CPPFLAGS
        if test -n "${BOOST_REGEX_HOME}"; then
            LDFLAGS="$LDFLAGS -L${BOOST_REGEX_HOME}/lib"
            CPPFLAGS="$CPPFLAGS -I${BOOST_REGEX_HOME}/include"
        fi
drok commented 5 months ago

Your build step shows -lboost_regex which is also mentioned in the other issues, no?

At the most superficial level, yes, my build step includes the word "-lboost_regex"