To help us debug your issue please explain:
conan version 1.2.3, Ubuntu 18.04
related to #2049 #2402
also https://github.com/bincrafters/community/issues/189
there is a problem with conan automatically appending -stdlib=libc++ flag in case of Android cross-compilation with standalone toolchain. as stdlib=libc++ implies -lc++, it fails, because NDK only has libc++_shared.so and libc++_static.so, but neither libc++.a nor libc++.so.
I've created a package which demonstrates the error: https://github.com/bincrafters/conan-android_ndk_installer
in order to reproduce errors, need to add two standard lines into the test_package/CMakeLists.txt:
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
given the simple profile:
cat ~/.conan/profiles/android
[settings]
compiler=clang
compiler.version=5.0
compiler.libcxx=libc++
os=Android
os.api_level=21
os_build=Linux
arch=armv7
arch_build=x86_64
build_type=Debug
and running conan create . bincrafters/testing -p android
the following error appears:
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/bin/clang++ --target=armv7-none-linux-androideabi --gcc-toolchain=/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d --sysroot=/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/sysroot -I/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/stable/package/ea4709a9bf32cba9b08ba74646bc157c4c17305b/include -I/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include -march=armv7-a -mthumb -mfpu=vfpv3-d16 -mfloat-abi=softfp -funwind-tables -no-canonical-prefixes -stdlib=libc++ -g -fPIE -o CMakeFiles/test_package.dir/test_package.cpp.o -c /home/sse4/conan/conan-android_ndk_installer/test_package/test_package.cpp
/home/sse4/conan/conan-android_ndk_installer/test_package/test_package.cpp:1:10: fatal error: 'cstdlib' file not found
#include <cstdlib>
^~~~~~~~~
1 error generated.
that may be solved by explicitly adding necessary directory to the includes:
def package_info(self)
...
self.cpp_info.includedirs.append(os.path.join(self.package_folder, 'include', 'c++', '4.9.x'))
however, linker error will appear next:
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/bin/clang++ --target=armv7-none-linux-androideabi --gcc-toolchain=/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d --sysroot=/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/sysroot -march=armv7-a -mthumb -mfpu=vfpv3-d16 -mfloat-abi=softfp -funwind-tables -no-canonical-prefixes -stdlib=libc++ -g -Wl,--fix-cortex-a8 -fPIE -pie -Wl,--gc-sections -Wl,-z,nocopyreloc CMakeFiles/test_package.dir/test_package.cpp.o -o bin/test_package -L/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/stable/package/ea4709a9bf32cba9b08ba74646bc157c4c17305b/lib -L/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/lib
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lc++
/home/sse4/conan/conan-android_ndk_installer/test_package/test_package.cpp:0: error: undefined reference to 'std::__ndk1::cout'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:756: error: undefined reference to 'std::__ndk1::ios_base::getloc() const'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/__locale:212: error: undefined reference to 'std::__ndk1::locale::use_facet(std::__ndk1::locale::id&) const'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:756: error: undefined reference to 'std::__ndk1::locale::~locale()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:756: error: undefined reference to 'std::__ndk1::locale::~locale()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:529: error: undefined reference to 'std::__ndk1::ios_base::clear(unsigned int)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:736: error: undefined reference to '__cxa_begin_catch'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:739: error: undefined reference to 'std::__ndk1::ios_base::__set_badbit_and_consider_rethrow()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:740: error: undefined reference to '__cxa_end_catch'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:740: error: undefined reference to '__cxa_end_catch'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:0: error: undefined reference to 'std::__ndk1::ctype<char>::id'
CMakeFiles/test_package.dir/test_package.cpp.o(.ARM.extab.text._ZNSt6__ndk124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j+0x0): error: undefined reference to '__gxx_personality_v0'
CMakeFiles/test_package.dir/test_package.cpp.o(.ARM.extab.text._ZNSt6__ndk116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_+0x0): error: undefined reference to '__gxx_personality_v0'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:274: error: undefined reference to 'std::uncaught_exception()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:529: error: undefined reference to 'std::__ndk1::ios_base::clear(unsigned int)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:283: error: undefined reference to '__cxa_begin_catch'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:286: error: undefined reference to '__cxa_end_catch'
CMakeFiles/test_package.dir/test_package.cpp.o(.ARM.extab.text._ZNSt6__ndk113basic_ostreamIcNS_11char_traitsIcEEE6sentryD2Ev+0x0): error: undefined reference to '__gxx_personality_v0'
CMakeFiles/test_package.dir/test_package.cpp.o:/home/sse4/conan/conan-android_ndk_installer/test_package/test_package.cpp:function __clang_call_terminate: error: undefined reference to '__cxa_begin_catch'
CMakeFiles/test_package.dir/test_package.cpp.o:/home/sse4/conan/conan-android_ndk_installer/test_package/test_package.cpp:function __clang_call_terminate: error: undefined reference to 'std::terminate()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ios:529: error: undefined reference to 'std::__ndk1::ios_base::clear(unsigned int)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:952: error: undefined reference to '__cxa_begin_catch'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:955: error: undefined reference to 'std::__ndk1::ios_base::__set_badbit_and_consider_rethrow()'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/ostream:956: error: undefined reference to '__cxa_end_catch'
CMakeFiles/test_package.dir/test_package.cpp.o(.ARM.extab.text._ZNSt6__ndk113basic_ostreamIcNS_11char_traitsIcEEE5flushEv+0x0): error: undefined reference to '__gxx_personality_v0'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/new:234: error: undefined reference to 'operator delete(void*)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/new:226: error: undefined reference to 'operator new(unsigned int)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:225: error: undefined reference to '__cxa_allocate_exception'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:136: error: undefined reference to 'std::logic_error::logic_error(char const*)'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:225: error: undefined reference to '__cxa_throw'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:225: error: undefined reference to '__cxa_free_exception'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:0: error: undefined reference to 'vtable for std::length_error'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:0: error: undefined reference to 'typeinfo for std::length_error'
/home/sse4/.conan/data/android_ndk_installer/r16b/bincrafters/testing/package/c03b64d50f54d253f88b5131dcccc04c72bc920d/include/c++/4.9.x/stdexcept:0: error: undefined reference to 'std::length_error::~length_error()'
clang50++: error: linker command failed with exit code 1 (use -v to see invocation)
it's because it cannot find -lc++, which barely doesn't exist at all.
commenting two lines in test_package/CMakeLists.txt results in no errors and no need for explicit directories.
as many existing recipes are using conan_basic_setup, and also flag is added to AutoToolsBuildEnvironment and probably other things as well, I guess it's not a sane default for Android.
official recommendation on std lib options doesn't mention -stdlib=libc++: https://developer.android.com/ndk/guides/standalone_toolchain
https://developer.android.com/ndk/guides/cpp-support
(as it also doesn't need explicit include/lib directories)
/cc @theodelrieu
IIRC from @theodelrieu conversations, wouldn't the solution be to remove the libcxx setting for Android packages? That might be enough to avoid the adding of the flag. If Android packages cannot use different C++ standard libraries, then, it is not a setting anymore, and should be removed (as in the case for C libraries),
@memsharded sorry, but I am afraid I disagree with you for two major reasons:
usage: make_standalone_toolchain.py [-h] --arch
{arm,arm64,mips,mips64,x86,x86_64}
[--api API]
[--stl {gnustl,libc++,stlport}] [--force]
[-v]
[--package-dir PACKAGE_DIR | --install-dir INSTALL_DIR]
however, right standard library is already baked into standalone toolchain, therefore you don't need additional flags to specify it during compilation. if you want to target different standard library implementation, then you have to build another standalone toolchain (via --stl option).
given that fact, android packages still need libcxx conan setting in order to distinguish these 3 implementations of standard library.
Oh, I see. I was wrong, I thought that the android toolchain had deprecated all the other stdlibs and were using just one, and the --stl argument was there for legacy reasons.
Then, yes, we should see if it is possible to automate this somehow, to not require modifying all recipes, thanks for the feedback!
Only libc++ will be available in the next NDK release. What I went with (thanks to @memsharded) was adding None to possible libcxx values in my settings.yml.
With this, I don't have to remove the setting explicitly in every recipe.
that's right, r18 will remove gnustl and stlport. but for current versions (r16 and r17 beta) they still exist, and probably we have to support em for a while.
Thanks @theodelrieu for the feedback, now I recall.
The issue with that approach is that we cannot generalize if for all users, cause adding None also slightly changes behavior (like not raising when libcxx is not defined), and there is the possibility that some binaries are duplicated for regular packages, so some extra care is necessary. It is doable in practice in your own setup, but slighthly breaking if we did in the defaults.
requiring libcxx=None for android also invalidates all existing packages, and requires building new packages with new package id, so this also makes suggested option doable.
@SSE4 @memsharded I am also hitting this issue. Has anyone found a workaround?
Removing the line
compiler.libcxx=libc++
Seems to do the work for me. Any suggestion or comment?
Edit: does not work at link time also for executable target. Missing mbstowcs in that case while it should be in the libc++ that is being included. Omitting compiler.libcxx=libc++ yields the -stdlib=libstdc++ compilation flag apparently.
@raffienficiaud The workaround would be to do
if self.settings.os == "Android":
cmake.definitions["CONAN_LIBCXX"] = ""
before calling cmake.configure(). But we need a proper fix.
@Paultergeist So ... the way I understand this right now is need to
compiler.libcxxlibc++ this standard gets translated to, either libc++_shared.so or libc++_static.aRight now, whatever appears in compiler.libcxx gets passed to the linker without transformation.
Do I understand the problem correctly?
@raffienficiaud You can look at the implementation here.
The problem is that Conan tries to be smart and not only use compiler.libcxx to match dependent packages, but also set some compiler switches. But when you build for Android with a standalone toolchain, this explicit linker flag (-stdlib=libc++ or -stdlib=libstdc++) causes linker error.
Thanks for pointing to the CMake source file causing this. I'll try to submit a patch very soon then.
@Paultergeist Preliminary work, please help me make it better !
I used @theodelrieu's android-ndk package to compile ICU library. Cross compiling from Mac OSX to android-armv7.
I get the following undefined references.
makeconv.o: In function `__clang_call_terminate':
makeconv.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x4): undefined reference to `__cxa_begin_catch'
makeconv.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x8): undefined reference to `std::terminate()'
makeconv.o:(.data.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
../../lib/libicuuc.a(putil.ao): In function `putil_cleanup()':
undefined reference to `operator delete(void*)'
undefined reference to `operator delete(void*)'
I think this might be due to some c++ run time linking error.
@theodelrieu Any idea why this might be happening? c++_static is being used here.
Could it be the difference in settings between cmake and configure tools( used by ICU)?
Hmm, looks like c++abi is not linked, could you open an issue in https://github.com/theodelrieu/conan-android-ndk?
@SSE4 I think this was fixed with the support of new settings in https://github.com/conan-io/conan/pull/4538/files
Please check and close the issue if so. Thanks! 馃槃
yes, it was, but I can't close an issue myself :)
Most helpful comment
@raffienficiaud The workaround would be to do
before calling
cmake.configure(). But we need a proper fix.