Opened 6 years ago

Last modified 3 years ago

#55733 accepted defect

lz4 @1.8.1.2: fails to build on systems following LibcxxOnOlderSystems — at Version 3

Reported by: grumpybozo (Bill Cole) Owned by:
Priority: Normal Milestone:
Component: ports Version: 2.4.2
Keywords: Cc:
Port: lz4

Description (last modified by ryandesign (Ryan Carsten Schmidt))

Errors are typical of missing C++11 support, even on a system where libcxx is installed and the procedure at LibcxxOnOlderSystems has been followed. A snippet:

make[1]: Entering directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_archivers_lz4/lz4/work/lz4-1.8.1.2/contrib/gen_manual'
/opt/local/bin/clang++-mp-5.0 -arch i386  -O3 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wno-comment   gen_manual.cpp -o gen_manual
Undefined symbols for architecture i386:
  "std::ctype<char>::_M_widen_init() const", referenced from:
      print_line(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) in gen_manual-327bb0.o
      _main in gen_manual-327bb0.o
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_not_of(char const*, unsigned long, unsigned long) const", referenced from:
      trim(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) in gen_manual-327bb0.o
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_first_not_of(char const*, unsigned long, unsigned long) const", referenced from:
      trim(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) in gen_manual-327bb0.o
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(char const*, unsigned long, unsigned long) const", referenced from:

This is solved by adding these lines to the Portfile:

depends_lib-append   lib:libc++.1:libcxx
configure.cxxflags   -stdlib=libc++
configure.cxx        clang++ -stdlib=libc++

Change History (4)

Changed 6 years ago by grumpybozo (Bill Cole)

Attachment: lz4.Portfile.patch added

Portfile patch for lz4 to add libc++ dependency

comment:1 Changed 6 years ago by kencu (Ken)

This is a manifestation of clang defaulting to add -stdlib=libstdc++ on systems prior to 10.9 if no stdlib is specified on the build line.

Your proposal will work on some systems (i.e. those like mine, which are set up with LibcxxOnOlderSystems), but this approach will most likely break on other systems, e.g. the systems that are using PortGroup cxx11 1.1, which is currently the MacPorts' default method of adding c++11 support.

A comprehensive fix that will work on all systems is likely to be more complex. See botan for an example.

comment:2 Changed 6 years ago by kencu (Ken)

By the way, although it's certainly great to fix up these ports one by one to send the right -stdlib to the compiler, the reason they stay broken for so long is that nobody on newer systems would ever notice this.

So if you ever get tired of fixing this particular issue on these older systems, it's really quite easy to change clang on your system to return the default stdlib you want (in your case, you want it to default to libc++). There is one function found in each version of clang that controls this. For clang-5.0 it lives here in:

tools/clang/lib/Driver/ToolChains/Darwin.cpp
ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
  // Default to use libc++ on OS X 10.9+ and iOS 7+.
  if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
       (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
       isTargetWatchOSBased())
    return ToolChain::CST_Libcxx;

  return ToolChain::CST_Libstdcxx;
}

I just change that

if ((isTargetMacOS() && !isMacosxVersionLT(10, 9))

to

if ((isTargetMacOS() && !isMacosxVersionLT(10, 4))

and then you get -stdlib=libc++ added by default on all systems, which is what you want.

comment:3 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Description: modified (diff)
Keywords: haspatch snowleopard i386 removed
Summary: lz4 fails to build on Snow Leopardlz4 @1.8.1.2: fails to build on systems following LibcxxOnOlderSystems

This is occurring because the port uses use_configure no, which means the portfile is responsible for supplying the correct flags to the build system, and this portfile has failed to do so.

Note: See TracTickets for help on using tickets.