Opened 6 years ago

Last modified 3 years ago

#55733 accepted defect

lz4 @1.8.1.2: fails to build on systems following LibcxxOnOlderSystems

Reported by: grumpybozo (Bill Cole) Owned by: ryandesign (Ryan Carsten Schmidt)
Priority: Normal Milestone:
Component: ports Version: 2.4.2
Keywords: Cc: mascguy (Christopher Nielsen)
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++

Attachments (1)

lz4.Portfile.patch (517 bytes) - added by grumpybozo (Bill Cole) 6 years ago.
Portfile patch for lz4 to add libc++ dependency

Download all attachments as: .zip

Change History (11)

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.

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

Owner: set to ryandesign
Status: newaccepted

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

Looking at this further, I don't know why it fails for you, so I'd appreciate it if you would attach the complete main.log file showing the failure.

The assumption that this software requires C++11 appears to be incorrect. C++ is only used to build the gen_manual program, which is only used to generate the manual. It builds fine with libstdc++ on Leopard with g++-4.2 which does not support C++11. In fact it builds on every macOS version we automatically build on (10.5–10.8 with libstdc++, 10.9–10.13 with libc++).

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

In 805cd044d8e54c39e05cb76375ec5aabc7ff1eb6/macports-ports:

lz4: Honor cxx_stdlib

See: #55733

No revision increase because C++ is only used to build the gen_manual
program, which is only used to build the manual. There is no change to
installed files.

comment:7 Changed 5 years ago by kencu (Ken)

I couldn't get this to build +universal on Leopard no matter what I tried -- always came to this:

Update lz4 manual in /doc
./gen_manual 1.8.3 ../../lib/lz4.h ../../doc/lz4_manual.html
make[1]: execvp: ./gen_manual: Bad CPU type in executable
make[1]: *** [../../doc/lz4_manual.html] Error 127
make[1]: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_archivers_lz4/lz4/work/lz4-1.8.3-x86_64/contrib/gen_manual'
make: *** [manuals] Error 2
make: *** Waiting for unfinished jobs....
make[1]: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_archivers_lz4/lz4/work/lz4-1.8.3-x86_64/lib'
make: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_archivers_lz4/lz4/work/lz4-1.8.3-x86_64'
Command failed:  cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_archivers_lz4/lz4/work/lz4-1.8.3-x86_64" && /usr/bin/make -j2 -w all CC=/opt/local/bin/clang-mp-3.4 CXX=/opt/local/bin/clang++-mp-3.4 PREFIX=/opt/local CFLAGS="-Os -arch x86_64" CXXFLAGS="-Os -stdlib=libstdc++ -arch x86_64" 
Exit code: 2
Error: Failed to build lz4: command execution failed

finally just disabling the manual by changing the build target to

build.target allmost

got around it and it installed.

comment:8 in reply to:  7 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Replying to kencu:

make[1]: execvp: ./gen_manual: Bad CPU type in executable

That's #57922.

comment:9 Changed 5 years ago by kencu (Ken)

As this issue is really 10.5 specific, would you be open to a PR that disables building the manual only on 10.5?

platform darwin 9 {
    build.target allmost
}

should do it.

comment:10 Changed 3 years ago by mascguy (Christopher Nielsen)

Cc: mascguy added
Note: See TracTickets for help on using tickets.