# we need LLVM_HOME in order not automatically set LLVM_DIR if(NOT DEFINED ENV{LLVM_HOME}) message(FATAL_ERROR "$LLVM_HOME is not defined") else () set(ENV{LLVM_DIR} $ENV{LLVM_HOME}/lib/cmake/llvm) endif()
➜ b git:(master) ✗ cmake .. CMake Error at /home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm/LLVMExports.cmake:806 (message): The imported target "LLVMDemangle" references the file
"/home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/lib64/libLLVMDemangle.a" but this file does not exist. Possible reasons include: * The file was deleted, renamed, or moved to another location. * An install or uninstall procedure did not complete successfully. * The installation package was faulty and contained "/home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm/LLVMExports.cmake"
but not all the files it references. Call Stack (most recent call first): /home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm/LLVMConfig.cmake:173 (include) CMakeLists.txt:8 (find_package)
-- Configuring incomplete, errors occurred! See also "/home/leadroyal/llvm-pass-tutorial/b/CMakeFiles/CMakeOutput.log".
因为NDK不含有.a文件,而cmake会检查这些文件,用于静态连接,被认为初始化失败,出错。
看源码对应的位置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Loop over all imported files and verify that they actually exist foreach(target ${_IMPORT_CHECK_TARGETS} ) foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) if(NOT EXISTS "${file}" ) message(FATAL_ERROR "The imported target \"${target}\" references the file \"${file}\" but this file does not exist. Possible reasons include: * The file was deleted, renamed, or moved to another location. * An install or uninstall procedure did not complete successfully. * The installation package was faulty and contained \"${CMAKE_CURRENT_LIST_FILE}\" but not all the files it references. ") endif() endforeach() unset(_IMPORT_CHECK_FILES_FOR_${target}) endforeach()
export LLVM_HOME=/home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64 ➜ b git:(master) ✗ cmake .. -- The C compiler identification is GNU 7.4.0 -- The CXX compiler identification is GNU 7.4.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- 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: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/leadroyal/llvm-pass-tutorial/b ➜ b git:(master) ✗ cmake --build . Scanning dependencies of target SkeletonPass [ 50%] Building CXX object skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o [100%] Linking CXX shared module libSkeletonPass.so [100%] Built target SkeletonPass
========GNU使用兼容libc++的方案 end ======= 我们先用简单的c文件验证我们的pass,没有任何问题
1 2 3 4 5 6 7 8 9 10
➜ /tmp cat test.c #include<stdio.h> int main(){ printf("HelloWorld\n"); return 0; } ➜ /tmp /home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -Xclang -load -Xclang /home/leadroyal/llvm-pass-tutorial/b/skeleton/libSkeletonPass.so test.c I saw a function called main! ➜ /tmp ./a.out HelloWorld
最后一步,见证奇迹的时刻!
1 2 3 4 5 6 7 8 9 10 11
➜ MyApplication ./gradlew clean build ............ > Task :app:externalNativeBuildDebug Build native-lib_armeabi-v7a ninja: Entering directory `/home/leadroyal/AndroidStudioProjects/MyApplication/app/.cxx/cmake/debug/armeabi-v7a' [1/2] Building CXX object CMakeFiles/native-lib.dir/native-lib.cpp.o I saw a function called Java_com_example_myapplication_MainActivity_stringFromJNI! I saw a function called _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2EPKc! I saw a function called _ZN7_JNIEnv12NewStringUTFEPKc! I saw a function called _ZNKSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv! I saw a function called _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev!
for bin_filename in os.listdir(bin_dir): binary = os.path.join(bin_dir, bin_filename) if os.path.isfile(binary): if bin_filename not in necessary_bin_files: remove(binary) elif strip and bin_filename not in script_bins: check_call(['strip', binary])