Opened 2 years ago

Closed 21 months ago

#53123 closed defect (fixed)

botan links against libstdc++ on 10.6 with libcxx, preventing qca from building. And workaround.

Reported by: kencu (Ken) Owned by: macports-tickets@…
Priority: Normal Milestone:
Component: ports Version:
Keywords: snowleopard Cc:
Port: botan

Description

on systems upgraded with LibcxxOnOlderSystems upgrading qca will likely fail as it did here:

:info:build [ 38%] Linking CXX shared module ../../lib/qca/crypto/libqca-botan.dylib
:info:build cd /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_qca/qca/work/build/plugins/qca-botan && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/qca-botan.dir/link.txt --verbose=ON
:info:build /opt/local/bin/clang++-mp-3.7  -pipe -Os -DNDEBUG -stdlib=libc++ -arch x86_64 -mmacosx-version-min=10.6 -bundle -Wl,-headerpad_max_install_names -L/opt/local/lib -Wl,-headerpad_max_install_names -o ../../lib/qca/crypto/libqca-botan.dylib CMakeFiles/qca-botan.dir/qca-botan.cpp.o -Wl,-rpath,/opt/local/lib /opt/local/libexec/qt4/lib/libQtCore.dylib ../../lib/libqca.2.1.0.dylib -L/opt/local/lib -lbotan-1.10 -lbz2 -lcrypto -lpthread -lz /opt/local/libexec/qt4/lib/libQtCore.dylib -framework Carbon -framework Security 
:info:build Undefined symbols for architecture x86_64:
:info:build   "Botan::get_cipher(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Botan::OctetString const&, Botan::Cipher_Dir)", referenced from:
:info:build       BotanCipherContext::setup(QCA::Direction, QCA::SymmetricKey const&, QCA::InitializationVector const&) in qca-botan.cpp.o
:info:build   "Botan::get_cipher(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Botan::OctetString const&, Botan::OctetString const&, Botan::Cipher_Dir)", referenced from:
:info:build       BotanCipherContext::setup(QCA::Direction, QCA::SymmetricKey const&, QCA::InitializationVector const&) in qca-botan.cpp.o
:info:build   "Botan::OctetString::change(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       Botan::OctetString::OctetString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in qca-botan.cpp.o
:info:build   "Botan::block_size_of(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanCipherContext::blockSize() const in qca-botan.cpp.o
:info:build   "Botan::Algorithm_Factory::prototype_mac(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanCipherContext::keyLength() const in qca-botan.cpp.o
:info:build   "Botan::Algorithm_Factory::make_hash_function(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanHashContext::BotanHashContext(QString const&, QCA::Provider*, QString const&) in qca-botan.cpp.o
:info:build       BotanHMACContext::BotanHMACContext(QString const&, QCA::Provider*, QString const&) in qca-botan.cpp.o
:info:build   "Botan::Algorithm_Factory::prototype_block_cipher(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanCipherContext::keyLength() const in qca-botan.cpp.o
:info:build   "Botan::Algorithm_Factory::prototype_stream_cipher(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanCipherContext::keyLength() const in qca-botan.cpp.o
:info:build   "Botan::LibraryInitializer::initialize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       botanProvider::init() in qca-botan.cpp.o
:info:build   "Botan::get_pbkdf(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
:info:build       BotanPBKDFContext::BotanPBKDFContext(QString const&, QCA::Provider*, QString const&) in qca-botan.cpp.o
:info:build ld: symbol(s) not found for architecture x86_64

the problem is not in qca, but in the library it's trying to link against, botan. It has built against libstdc++, instead of libc++.

$ otool -L /opt/local/lib/libbotan-1.10.dylib
/opt/local/lib/libbotan-1.10.dylib:
	/opt/local/lib/libbotan-1.10.dylib.0 (compatibility version 0.0.0, current version 0.0.0)
	/opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
	/opt/local/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
	/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)

The fix, as always, is to get -stdlib=libc++ onto the build line. Usually this happens automagically, but looking over the Portfile for botan, you can see there are some nonstandard things done to get it to work.

There are different ways you might do that, but one way is to add it to the build.args line in the botan portfile. In this case, I'm just building x86_64, so it can go here:

           x86_64 {
                build.args CXX="${configure.cxx} -m64 -stdlib=libc++"
            }

no doubt, there is a better way to do it.

Then, force a rebuild of botan sudo port -v -n upgrade --force botan which will now hopefully build against libc++, and it does:

$ otool -L /opt/local/lib/libbotan-1.10.dylib
/opt/local/lib/libbotan-1.10.dylib:
	/opt/local/lib/libbotan-1.10.dylib.0 (compatibility version 0.0.0, current version 0.0.0)
	/opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
	/opt/local/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
	/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 3.9.0)
	/usr/lib/libc++abi.dylib (compatibility version 1.0.0, current version 3.9.0)

and then the upgrade of qca can proceed, without further link errors:

$ port -v installed | grep qca
  qca @2.1.0_3+qt4 platform='darwin 10' archs='x86_64'
  qca @2.1.0_4 (active) platform='darwin 10' archs='x86_64'

hope this helps someone. This is the second time I've come across this issue in as many days... I wonder if there could be a more generic fix for this, such as adding something like this somewhere where it will be found widely...

CXX="${configure.cxx} -stdlib=libc++"

Change History (6)

comment:1 Changed 2 years ago by mf2k (Frank Schima)

Cc: mww@… removed
Keywords: snowleopard added
Owner: set to mww@…
Status: newassigned

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

I'm going to try a different, more comprehensive approach to this issue. I patched macports-clang-3.x to default to -stdlib=libc++ instead of -stdlib=libstdc++ on all systems, including 10.6.

So far, it fixes the issue with botan, and I think it will also solve the wx-widgets issue and the leveldb issue as well.

Will see how it goes. If it works well, Jeremy can decide if that's appropriate or not for general use.

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

The slightly patched versions of clang-3.7, clang-3.8, and clang-3.9 have indeed solved this problem for me (and the other listed problems in comment 2 above).

Jeremy quite correctly points out that changing the default behaviour of a compiler can have unforeseen troubles, so he doesn't recommend this approach for general use at present.

comment:4 Changed 2 years ago by kurthindenburg (Kurt Hindenburg)

Owner: changed from mww@… to macports-tickets@…

comment:5 Changed 21 months ago by kencu (Ken)

Still lots of troubles with botan -- on a 10.7 machine it needs to be installed with cxx11 1.1 to support qt5-qtcreator, and in doing so the c++ standard lib linkages are all wrong. I found this block in db60 which works nicely when added to botan, though, to fix this issue by adding the standard library setting onto the compiler spec:

set cxx_stdlibflags {}
if {[string match *clang* ${configure.cxx}]} {
    set cxx_stdlibflags -stdlib=${configure.cxx_stdlib}
}
configure.cxx ${configure.cxx} ${cxx_stdlibflags}

comment:6 Changed 21 months ago by System Administrator <root@…>

Resolution: fixed
Status: assignedclosed

In 1cb72605843b6d53d6a71f77d2f433253466f29c/macports-ports:

botan: respect -stdlib settings when building with clang

closes: #53123

Note: See TracTickets for help on using tickets.