Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing libgcc in libc++.a breaks clang c++_static build #515

Closed
AstralStorm opened this issue Sep 11, 2017 · 11 comments
Closed

Missing libgcc in libc++.a breaks clang c++_static build #515

AstralStorm opened this issue Sep 11, 2017 · 11 comments
Assignees

Comments

@AstralStorm
Copy link

AstralStorm commented Sep 11, 2017

Libunwind is missing for x86, x86_64 and arm64-v8a ABI preventing correct static linking with c++_static when exceptions are enabled.
This is caused by libc++abi directly referencing _Unwind_* symbols.

Results in errors like:
undefined reference to "_Unwind_Resume" etc.

Tested with NDK 16 beta 1, clang c++_static build of a shared library, ANDROID_CPP_FEATURES=exceptions and actually used exception handling.
Build is fine on armeabi-v7a and armeabi which provide libunwind.
Fails on x86, x86_64 and arm64-v8a. (Probably mips etc. as well but haven't checked.)

@AstralStorm AstralStorm changed the title Missing libunwind for x86, x86_64 and arm64-v8a Missing libunwind for other archs than armeabi and armeabi-v7a Sep 11, 2017
@AstralStorm AstralStorm changed the title Missing libunwind for other archs than armeabi and armeabi-v7a Missing static libunwind for other archs than armeabi and armeabi-v7a Sep 11, 2017
@AstralStorm
Copy link
Author

AstralStorm commented Sep 11, 2017

After some more digging, it seems that older Android.mk properly linked libunwindbacktrace into libc++abi on non-armeabi, but the new Android.mk and soong Android.bp is missing the link instructions. Instead a define is set but apparently it is not sufficient.

@DanAlbert
Copy link
Member

Those platforms don't use libunwind. They use libgcc. Can you share your CMake configuration command?

@AstralStorm
Copy link
Author

AstralStorm commented Sep 13, 2017

Oh that changes things. It is related to #504 and ancient android.toolchain.cmake then. It doesn't add libc++abi etc. on its own so I had to help it.

However, new setup from CMake git master seems to attempt to link libunwind not libgcc after source code inspection. See: https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/Android/ndk-stl-c++_static.cmake

@AstralStorm AstralStorm changed the title Missing static libunwind for other archs than armeabi and armeabi-v7a Missing libgcc in libc++.a Sep 13, 2017
@AstralStorm
Copy link
Author

AstralStorm commented Sep 13, 2017

Another error that finally showed up on armeabi-v7a is missing __aeabi_uldivmod etc. when trying to use or . This is due to missing libgcc lin libc++.a while it is depended upon. (Note that adding -lgcc there does not work as it is not in the same directory.)
Apparently libc++_static.a does not include it.

Adding the linkage against the right libgcc.a per target works around it.

@AstralStorm AstralStorm changed the title Missing libgcc in libc++.a Missing libgcc in libc++.a breaks clang c++_static build Sep 13, 2017
@DanAlbert
Copy link
Member

DanAlbert commented Sep 13, 2017

Another error that finally showed up on armeabi-v7a is missing __aeabi_uldivmod etc... Apparently libc++_static.a does not include it.

It's not supposed to.

Can you share your CMake configuration command?

@AstralStorm
Copy link
Author

AstralStorm commented Sep 14, 2017

First, there's #105 which masks the problem as libstdc++.so contains the required symbols. Once you work around it (e.g. with -nodefaultlibs) and link like so:
string(CONCAT CMAKE_CXX_FLAGS "-nodefaultlibs " "${CMAKE_CXX_FLAGS}")
string(CONCAT CMAKE_CXX_STANDARD_LIBRARIES "-lc -ldl " "${CMAKE_CXX_STANDARD_LIBRARIES}")
Note that CMAKE_CXX_STANDARD_LIBRARIES does contain the correct path to libc++.a added by toolchain file.

You will find you're missing libgcc. Adding -lgcc does not work, as it does not exist in Clang search path. Upcoming -nostdlibc++ flag will probably not link libgcc as well in the new unreleased upcoming Clang. Adding -static-libgcc does not work either.
Issue is reproducible with both NDK's android.toolchain.cmake, with Android Studio CMake 3.6.x's and with new CMake 3.9.2 from master.

Adding something like e.g.
string(CONCAT CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES}"
" ${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a")
(for arm) works around it.

@DanAlbert
Copy link
Member

Can you share your CMake configuration command?

@AstralStorm
Copy link
Author

AstralStorm commented Sep 14, 2017

It is ran by gradle plugin 3.0.0-beta5, externalNativeBuild, the options are:

externalNativeBuild {
            cmake {
                cFlags "-std=c11"
                cppFlags "-std=c++14 -D_LIBCPP_STD_VER=14"
                abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
                arguments "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_STL=c++_static",
                        "-DCMAKE_TOOLCHAIN_FILE=${android.ndkDirectory}/build/cmake/android.toolchain.cmake",
                        "-DANDROID_CPP_FEATURES=rtti exceptions", "-DANDROID_TOOLCHAIN=clang",
            }
}

The define is to force older versions of gradle plugin to actually use the right CMAKE_TOOLCHAIN_FILE.

Slightly anonymized output of one of cmake_build_command.txt:

Executable : android/sdk/cmake/3.6.4111459/bin/cmake
arguments : 
-HabsoluteProjectPath
-BabsoluteProjectPath/.externalNativeBuild/cmake/debug/armeabi-v7a
-DCMAKE_SYSTEM_NAME=Android
-DANDROID_ABI=armeabi-v7a
-DANDROID_PLATFORM=android-21
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=absoluteProjectPath/build/intermediates/cmake/debug/obj/armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_MAKE_PROGRAM=android/sdk/cmake/3.6.4111459/bin/ninja
-DCMAKE_C_FLAGS=-std=c11
-DCMAKE_CXX_FLAGS=-std=c++14 -D_LIBCPP_STD_VER=14
-DANDROID_ARM_MODE=arm
-DANDROID_ARM_NEON=TRUE
-DANDROID_STL=c++_static
-DCMAKE_TOOLCHAIN_FILE=android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DANDROID_CPP_FEATURES=rtti exceptions
-DANDROID_TOOLCHAIN=clang
-DCMAKE_TOOLCHAIN_FILE=android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DANDROID_NDK=android/sdk/ndk-bundle
-GAndroid Gradle - Ninja
jvmArgs : 

@DanAlbert DanAlbert self-assigned this Sep 14, 2017
@DanAlbert
Copy link
Member

Works fine for me. My guess is that you're using some prebuilt libraries that need to be rebuilt.

Everything reported here so far is actually things working as expected (using libgcc instead of libunwind, static libs not having libgcc symbols in them). Without a repro case there's nothing more we can do here.

@AstralStorm
Copy link
Author

AstralStorm commented Sep 15, 2017

Hmm, no idea why would I need libraries to be rebuilt at all since when linking libgcc.a directly it works.

The problem really shows up only with armeabi-v7a and std::chrono use (in my specific case, std::timed_mutex::wait_for(1min) with using std::chrono_literals on top) - anything else works without libgcc.a on that; without libgcc.a you get __aeabi_uldivmod etc. missing.
Other platforms also work unless you use exceptions there, in which case they are missing _Unwind_* symbols.

Make sure your test result is not linked against libstdc++.so - which has all the libgcc symbols inside and obviously works. (I checked with readelf -d libproject.so.) That is issue #105 - I had to work around it as mentioned above with the two mentioned CMakeLists.txt lines.

I'll produce a test project a while later.

@DanAlbert
Copy link
Member

Closing for lack of a repro case. Will reopen if we get something actionable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants