kpu / kenlm

KenLM: Faster and Smaller Language Model Queries
http://kheafield.com/code/kenlm/
Other
2.5k stars 513 forks source link

Android forces linkage against pthread and rt which are not exposed as libraries #301

Closed lissyx closed 4 years ago

lissyx commented 4 years ago

As per https://developer.android.com/ndk/guides/stable_apis#c_library, pthread and rt are not separate libs but rather in libc. However, when trying to cross-compile KenLM for Android, linkage fails because of forced -lpthread -lrt flags.

e.g.:

$ Boost_DIR=/home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/cmake/Boost-1.72.0/ cmake -DFORCE_STATIC=ON -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a -DCMAKE_ANDROID_NDK=$HOME/codaz/Android/android-ndk-r18b/ -DCMAKE_ANDROID_STL_TYPE=c++_static ../
$ make -j8 lmplz
[...]
[ 98%] Linking CXX executable ../../bin/lmplz                                                                                                                                                                                                                                                                                                                           
cd /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/kenlm/build/lm/builder && /usr/bin/cmake -E cmake_link_script CMakeFiles/lmplz.dir/link.txt --verbose=1
/home/alex/codaz/Android/android-ndk-r18b//toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android --gcc-toolchain=/home/alex/codaz/Android/android-ndk-r18b//toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 --sysroot=/home/alex/codaz/Android/android-ndk-r18b//platforms/android-21/arch-arm64  -funwind-tables -no-canonic
al-prefixes -D__ANDROID_API__=21 -fexceptions -frtti -g  -fPIE -pie -Wl,--gc-sections CMakeFiles/lmplz.dir/lmplz_main.cc.o  -o ../../bin/lmplz  ../../lib/libkenlm_builder.a ../../lib/libkenlm.a ../../lib/libkenlm_util.a /home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/libboost_program_options.a /home/alex/codaz/Mozilla/DeepSpeech/ndk_21
_boost_1.72.0/libs/arm64-v8a/libboost_system.a /home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/libboost_thread.a /home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/libboost_unit_test_framework.a -lpthread /home/alex/codaz/Android/android-ndk-r18b/platforms/android-21/arch-arm64/usr/lib/libz.a  "/home/alex/codaz/Andr
oid/android-ndk-r18b//sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a" "/home/alex/codaz/Android/android-ndk-r18b//sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a" -latomic -nostdlib++                                                                                                                                                              
/home/alex/codaz/Android/android-ndk-r18b//toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: cannot find -lpthread                                                                                                                                                               
clang++: error: linker command failed with exit code 1 (use -v to see invocation)     
make[3]: *** [lm/builder/CMakeFiles/lmplz.dir/build.make:92 : bin/lmplz] Erreur 1                                                                                                   
make[3] : on quitte le répertoire « /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/kenlm/build »    
make[2]: *** [CMakeFiles/Makefile2:485 : lm/builder/CMakeFiles/lmplz.dir/all] Erreur 2                                                                                                                                                                                                                                                                                  
make[2] : on quitte le répertoire « /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/kenlm/build »                                                               
make[1]: *** [CMakeFiles/Makefile2:492 : lm/builder/CMakeFiles/lmplz.dir/rule] Erreur 2                                                                                             
make[1] : on quitte le répertoire « /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/kenlm/build »    
make: *** [Makefile:268 : lmplz] Erreur 2                                                                                                                                                                                                                                                                                                                               

Hacking into CMakeLists.txt and disabling pthread and rt successfully links binaries. Is there some magic feature to cross-compile for Android that I missed while searching for docs, or is it just a legit issue?

kpu commented 4 years ago

Does it work now?

lissyx commented 4 years ago

Does it work now?

Waouh, that was quick, let me check on my side!

lissyx commented 4 years ago

Hm looks like not on rt side:

$ Boost_DIR=/home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/cmake/Boost-1.72.0/ cmake -DFORCE_STATIC=ON -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a -DCMAKE_ANDROID_NDK=$HOME/codaz/Android/android-ndk-r18b/ -DCMAKE_AND
ROID_STL_TYPE=c++_static ../
-- Android: Targeting API '21' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64'
-- Android: Selected Clang toolchain 'aarch64-linux-android-clang' with GCC toolchain 'aarch64-linux-android-4.9'
-- The C compiler identification is Clang 7.0.2
-- The CXX compiler identification is Clang 7.0.2
-- Check for working C compiler: /home/alex/codaz/Android/android-ndk-r18b//toolchains/llvm/prebuilt/linux-x86_64/bin/clang
-- Check for working C compiler: /home/alex/codaz/Android/android-ndk-r18b//toolchains/llvm/prebuilt/linux-x86_64/bin/clang -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /home/alex/codaz/Android/android-ndk-r18b//toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
-- Check for working CXX compiler: /home/alex/codaz/Android/android-ndk-r18b//toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Boost: /home/alex/codaz/Mozilla/DeepSpeech/ndk_21_boost_1.72.0/libs/arm64-v8a/cmake/Boost-1.72.0/BoostConfig.cmake (found suitable version "1.72.0", minimum required is "1.41.0") found components: program_options system thread unit_test_framework 
-- Found Threads: TRUE  
-- Found ZLIB: /home/alex/codaz/Android/android-ndk-r18b/platforms/android-21/arch-arm64/usr/lib/libz.a (found version "1.2.7") 
-- Could NOT find BZip2 (missing: BZIP2_LIBRARIES) (found version "1.0.8")
-- Could NOT find LibLZMA (missing: LIBLZMA_LIBRARY LIBLZMA_HAS_AUTO_DECODER LIBLZMA_HAS_EASY_ENCODER LIBLZMA_HAS_LZMA_PRESET) (found version "5.2.4")
-- Found Eigen3: /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/eigen-3.3.7 (Required is at least version "2.91.0") 
-- Found OpenMP_C: -fopenmp=libomp (found version "3.1") 
-- Found OpenMP_CXX: -fopenmp=libomp (found version "3.1") 
-- Found OpenMP: TRUE (found version "3.1")  
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBRT
    linked by target "kenlm_util" in directory /home/alex/codaz/Mozilla/DeepSpeech/deepspeech-kdavis/kenlm/util

-- Configuring incomplete, errors occurred!
lissyx commented 4 years ago

@kpu still need to:

diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
index 4655444..2033cea 100644
--- a/util/CMakeLists.txt
+++ b/util/CMakeLists.txt
@@ -57,7 +57,9 @@ set_source_files_properties(file_piece_test.cc PROPERTIES COMPILE_FLAGS ${READ_C
 add_subdirectory(double-conversion)
 add_subdirectory(stream)

-find_library(LIBRT rt)
+if (NOT ANDROID)
+  find_library(LIBRT rt)
+endif()

 # Group these objects together for later use.
 add_library(kenlm_util ${KENLM_UTIL_DOUBLECONVERSION_SOURCE} ${KENLM_UTIL_STREAM_SOURCE} ${KENLM_UTIL_SOURCE})
lissyx commented 4 years ago

Also cross-compilation on Linux ARM64 and ARMv7 now seems to require an extra argument, unsure if that is expected:

CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately:
   THREADS_PTHREAD_ARG (advanced)
kpu commented 4 years ago

With regard to TRY_RUN, how old is your cmake? Before or after this? https://gitlab.kitware.com/cmake/cmake/-/merge_requests/1109

lissyx commented 4 years ago

With regard to TRY_RUN, how old is your cmake? Before or after this? https://gitlab.kitware.com/cmake/cmake/-/merge_requests/1109

3.5.1 from ubuntu 16.04: https://packages.ubuntu.com/xenial/cmake

There's no tracking flags on cmake, so I don't know if it's in this release, but judging from the "3 years ago" and that this is 16.04, I'd guess no

lissyx commented 4 years ago

Well at least -DTHREADS_PTHREAD_ARG=2 unblocks the TRY_RUN thing.

lissyx commented 4 years ago

@kpu still need to:

diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
index 4655444..2033cea 100644
--- a/util/CMakeLists.txt
+++ b/util/CMakeLists.txt
@@ -57,7 +57,9 @@ set_source_files_properties(file_piece_test.cc PROPERTIES COMPILE_FLAGS ${READ_C
 add_subdirectory(double-conversion)
 add_subdirectory(stream)

-find_library(LIBRT rt)
+if (NOT ANDROID)
+  find_library(LIBRT rt)
+endif()

 # Group these objects together for later use.
 add_library(kenlm_util ${KENLM_UTIL_DOUBLECONVERSION_SOURCE} ${KENLM_UTIL_STREAM_SOURCE} ${KENLM_UTIL_SOURCE})

@kpu It also seems to break on macOS:


CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBRT
    linked by target "kenlm_util" in directory /Users/build-user/TaskCluster/Workdir/tasks/tc-workdir/DeepSpeech/ds/kenlm/util
lissyx commented 4 years ago

@kpu Trivially, this seems to work:

diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
index 4655444..caca2bd 100644
--- a/util/CMakeLists.txt
+++ b/util/CMakeLists.txt
@@ -57,7 +57,9 @@ set_source_files_properties(file_piece_test.cc PROPERTIES COMPILE_FLAGS ${READ_C
 add_subdirectory(double-conversion)
 add_subdirectory(stream)

-find_library(LIBRT rt)
+if (NOT ANDROID AND NOT APPLE)
+  find_library(LIBRT rt)
+endif()

 # Group these objects together for later use.
 add_library(kenlm_util ${KENLM_UTIL_DOUBLECONVERSION_SOURCE} ${KENLM_UTIL_STREAM_SOURCE} ${KENLM_UTIL_SOURCE})

I still have other CI issues to fix before being out of the woods for Android, but this did built a macOS package successfully. I can throw a PR if you feel this is a legit fix.

kpu commented 4 years ago

I've updated to gate librt and added continuous integration for Mac.

lissyx commented 4 years ago

I've updated to gate librt and added continuous integration for Mac.

OK, and it seems you moved forward and integrated similar fix for rt, I'll test that as well. Thanks for teh quick feedback!

lissyx commented 4 years ago

Yes, I can confirm that current master 689a25aae9171b3ea46bd80d4189f540f35f1a02 is fine as well on my side! Thanks again!