chaquo / chaquopy

Chaquopy: the Python SDK for Android
https://chaquo.com/chaquopy/
MIT License
847 stars 133 forks source link

Facing issues compiling mecab #802

Closed wangziyannb closed 2 years ago

wangziyannb commented 2 years ago

I'm trying to compile a c++ library called mecab. Everything goes fine until it tries to use libstdc++.so to compile libmecab.so.

This is the output from the console:

/bin/bash ../libtool --tag=CXX --mode=link /root/target/toolchains/arm64-v8a/bin/aarch64-linux-android-g++ -O3 -Wall -Wl,--no-undefined -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libunwind.a -lm -o mecab mecab.o libmecab.la -lpthread -lpthread -lstdc++ libtool: link: /root/target/toolchains/arm64-v8a/bin/aarch64-linux-android-g++ -O3 -Wall -Wl,--no-undefined -Wl,--exclude-libs -Wl,libgcc.a -Wl,--exclude-libs -Wl,libgcc_real.a -Wl,--exclude-libs -Wl,libunwind.a -o .libs/mecab mecab.o -lm ./.libs/libmecab.so -lpthread -lstdc++ /root/target/toolchains/arm64-v8a/bin/../lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: warning: libstdc++.so, needed by ./.libs/libmecab.so, not found (try using -rpath or -rpath-link) ./.libs/libmecab.so: undefined reference to__cxa_pure_virtual@LIBC_O' ./.libs/libmecab.so: undefined reference to operator delete[](void*)@LIBC_O' ./.libs/libmecab.so: undefined reference tooperator new[](unsigned long)@LIBC_O' ./.libs/libmecab.so: undefined reference to operator new(unsigned long, std::nothrow_t const&)@LIBC_O' ./.libs/libmecab.so: undefined reference tooperator new(unsigned long)@LIBC_O' ./.libs/libmecab.so: undefined reference to std::nothrow@LIBC_O' ./.libs/libmecab.so: undefined reference tooperator delete(void*)@LIBC_O' clang90++: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [mecab] Error 1 Makefile:463: recipe for target 'mecab' failed make[2]: Leaving directory '/root/pypi/packages/mecab/build/1/py3-none-android_21_arm64_v8a/src/src' `

After searching some materials about NDK, I find this link:

For completeness, in older NDKs libstdc++ (the GNU C++ runtime) was also included in the NDK, but as of NDK r18 that is no longer the case.

I'm not good at cross-compiling and NDK, so what can I do to fix this? Do I need to manually define an older NDK version or use some magic to force it to compile using libc++?

The mecab repo is here,, build dir is mecab inside. (mecab/mecab) To compile it in armv8i, I use a newer version config.sub from gcc

I'm using the same build.sh from chaquopy-libzmq, just a minor chage: ./configure --host=$HOST_TRIPLET --enable-utf8-only

Any help is appreciated.

mhsmith commented 2 years ago

In the current NDK, the C++ standard library is called "libc++_shared.so". However, the C++ compiler will link against it automatically, so the solution is just to remove the explcit dependency on libstdc++. You can do this with the following patch:

--- a/mecab/configure.in
+++ b/mecab/configure.in
@@ -50,7 +50,7 @@ AC_TYPE_SIZE_T
 AC_TYPE_UNSIGNED_LONG_LONG_INT

 AC_FUNC_MMAP
-AC_CHECK_LIB(stdc++, main, MECAB_LIBS="-lstdc++")
+# AC_CHECK_LIB(stdc++, main, MECAB_LIBS="-lstdc++")  # Chaquopy: disabled
 AC_CHECK_LIB(pthread,pthread_create)
 AC_CHECK_LIB(pthread,pthread_join)
 AC_CHECK_FUNCS(getenv)

Then, to regenerate configure from configure.in, you'll have to add the following line to build.sh before calling ./configure:

./autogen.sh

As described in https://github.com/chaquo/chaquopy/issues/791, I usually test changes like this using the --no-unpack option, and then create a permanent patch in the patches subdirectory once everything's working.

wangziyannb commented 2 years ago

Huge thanks to you! I finally succeeded to compile this library for chaquopy. By the way, autogen.sh requires libtool in docker env so I have to modify server/pypi/Dockerfile to do that.