在Ubuntu 20.04上为Android ARM64编译LLVM 15.0.7的保姆级避坑指南(附NDK 24配置)

张开发
2026/4/23 18:17:38 15 分钟阅读

分享文章

在Ubuntu 20.04上为Android ARM64编译LLVM 15.0.7的保姆级避坑指南(附NDK 24配置)
在Ubuntu 20.04上为Android ARM64编译LLVM 15.0.7的保姆级避坑指南附NDK 24配置当Android NDK官方预编译的工具链无法满足特定需求时自行编译LLVM成为解决定制化问题的终极方案。本文将带您从零开始在Ubuntu 20.04系统上为ARM64架构的Android设备编译LLVM 15.0.7并详细解决编译过程中可能遇到的各种坑。1. 环境准备与源码获取1.1 系统与工具要求确保您的Ubuntu 20.04系统已安装以下基础工具sudo apt update sudo apt install -y \ git cmake ninja-build \ python3 python3-pip \ g make zlib1g-dev注意建议使用物理机而非虚拟机进行编译LLVM编译过程对CPU和内存资源消耗较大。1.2 获取LLVM源码使用git克隆LLVM项目源码并切换到15.0.7版本git clone --depth 1 --branch llvmorg-15.0.7 https://github.com/llvm/llvm-project.git cd llvm-project提示添加--depth 1参数可以显著减少下载时间但会丢失历史提交记录。1.3 Android NDK配置下载NDK 24并设置环境变量wget https://dl.google.com/android/repository/android-ndk-r24-linux-x86_64.zip unzip android-ndk-r24-linux-x86_64.zip export ANDROID_NDK$(pwd)/android-ndk-r242. 关键CMake脚本修改LLVM源码中有几个模块在Android环境下会导致编译失败需要进行针对性修改。2.1 修改LLVMHello模块编辑llvm/lib/Transforms/CMakeLists.txt文件# 原始内容 add_llvm_library(LLVMHello MODULE BUILDTREE_ONLY Hello.cpp DEPENDS intrinsics_gen PLUGIN_TOOL opt ) # 修改为 if(NOT ANDROID) add_llvm_library(LLVMHello MODULE BUILDTREE_ONLY Hello.cpp DEPENDS intrinsics_gen PLUGIN_TOOL opt ) endif()2.2 修改BugpointPasses模块编辑llvm/tools/bugpoint-passes/CMakeLists.txt# 原始内容 add_llvm_library(BugpointPasses MODULE BUILDTREE_ONLY TestPasses.cpp DEPENDS intrinsics_gen bugpoint ) # 修改为 if(NOT ANDROID) add_llvm_library(BugpointPasses MODULE BUILDTREE_ONLY TestPasses.cpp DEPENDS intrinsics_gen bugpoint ) endif()2.3 修改Bye示例模块编辑llvm/examples/Bye/CMakeLists.txt# 原始内容 add_llvm_pass_plugin(Bye Bye.cpp DEPENDS intrinsics_gen BUILDTREE_ONLY ) install(TARGETS ${name} RUNTIME DESTINATION ${LLVM_EXAMPLES_INSTALL_DIR}) set_target_properties(${name} PROPERTIES FOLDER Examples) # 修改为 if(NOT WIN32 AND NOT ANDROID) add_llvm_pass_plugin(Bye Bye.cpp DEPENDS intrinsics_gen BUILDTREE_ONLY ) install(TARGETS ${name} RUNTIME DESTINATION ${LLVM_EXAMPLES_INSTALL_DIR}) set_target_properties(${name} PROPERTIES FOLDER Examples) endif()3. 编译配置与执行3.1 创建编译脚本创建build_android.sh文件内容如下#!/bin/bash # 设置路径变量 build_dir$(pwd)/build-android install_dir$(pwd)/install-android llvm_dir$(pwd)/llvm-project # 创建构建目录 mkdir -p $build_dir mkdir -p $install_dir # 配置CMake cmake -G Ninja -S $llvm_dir/llvm -B $build_dir \ -DLLVM_ENABLE_PROJECTSclang;libcxx;libcxxabi \ -DCMAKE_TOOLCHAIN_FILE$ANDROID_NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABIarm64-v8a \ -DANDROID_PLATFORMandroid-24 \ -DCMAKE_INSTALL_PREFIX$install_dir \ -DLLVM_INCLUDE_TESTSOFF \ -DLLVM_BUILD_TESTSOFF \ -DLLVM_INCLUDE_BENCHMARKSOFF \ -DCMAKE_BUILD_TYPERelease # 开始编译 ninja -C $build_dir install -j$(nproc)3.2 执行编译给脚本添加执行权限并运行chmod x build_android.sh ./build_android.sh编译过程可能需要数小时具体时间取决于您的硬件配置。建议使用高性能CPU至少8核分配足够的内存建议16GB以上使用SSD存储加速编译4. 部署与测试4.1 将编译结果推送到Android设备adb connect 设备IP adb push ./install-android /data/local/tmp/llvm4.2 解决头文件缺失问题在Android设备上编译时可能会遇到标准库头文件缺失的问题。解决方法# 从NDK中复制必要的头文件 cp -r $ANDROID_NDK/sysroot/usr/include $install_dir/usr/然后在编译时添加包含路径./bin/clang main.cc \ -I include/c/v1 \ -I usr/include \ -I usr/local/include \ -I usr/include/aarch64-linux-android4.3 解决链接器缺失问题Android设备上可能缺少必要的链接器工具解决方案编译ARM64版本的binutils工具链将编译好的ld工具复制到Android设备的/data/local/tmp/llvm/bin目录设置环境变量export PATH$PATH:/data/local/tmp/llvm/bin5. 常见问题与解决方案5.1 编译过程中内存不足如果遇到内存不足导致编译失败可以尝试减少并行编译任务数将-j$(nproc)改为-j4增加系统交换空间sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile5.2 CMake配置错误如果CMake配置阶段失败检查NDK路径是否正确设置系统是否安装了所有依赖项CMake版本是否足够新至少3.13.45.3 运行时符号找不到在Android设备上运行时如果遇到symbol not found错误可能需要设置正确的LD_LIBRARY_PATHexport LD_LIBRARY_PATH/data/local/tmp/llvm/lib:$LD_LIBRARY_PATH静态链接相关库./bin/clang -static main.cc6. 性能优化与高级配置6.1 启用LTO链接时优化在CMake配置中添加-DLLVM_ENABLE_LTOThin这可以显著提高生成代码的性能但会增加编译时间和内存消耗。6.2 选择性编译组件如果只需要特定组件可以修改-DLLVM_ENABLE_PROJECTS参数。例如仅编译Clang-DLLVM_ENABLE_PROJECTSclang6.3 交叉编译其他Android架构要编译其他架构如armeabi-v7a只需修改-DANDROID_ABI参数-DANDROID_ABIarmeabi-v7a7. 实际应用案例7.1 使用自定义LLVM编译Android NDK项目在Android.mk或CMakeLists.txt中指定自定义工具链set(CMAKE_C_COMPILER /data/local/tmp/llvm/bin/clang) set(CMAKE_CXX_COMPILER /data/local/tmp/llvm/bin/clang)7.2 启用实验性功能如果需要使用LLVM中的实验性功能如新的优化pass可以在编译时启用-DLLVM_ENABLE_EXPERIMENTALON7.3 调试信息生成为了便于调试可以生成调试信息-DCMAKE_BUILD_TYPERelWithDebInfo8. 维护与更新8.1 更新LLVM版本要更新到新版本LLVMgit fetch --tags git checkout llvmorg-16.0.0 # 示例切换到16.0.0版本 git submodule update --init --recursive然后重新执行编译流程。8.2 创建补丁文件对源码的修改可以保存为补丁文件方便后续使用git diff android_arm64.patch应用补丁git apply android_arm64.patch8.3 二进制分发可以将编译好的工具链打包分发tar -czvf llvm-15.0.7-android-arm64.tar.gz install-android

更多文章