cmake交叉编译:寻找工具

Cmake cross compiling: finding tools

我正在使用由 android ndk13b 制作的独立工具链。它工作正常,但要找到所有工具(链接器、存档器等),我的工具链文件中有一个非常冗长的部分。 有没有办法让它更紧凑?

SET(COMPILER_PATH   "<path_to_my_llvm_directory>")

SET(CMAKE_TOOLCHAIN_PREFIX aarch64-linux-android-) #In theory should allow to find minor tools like ar and objdump, see 
find_program(CMAKE_C_COMPILER   clang.cmd PATH ${COMPILER_PATH})
find_program(CMAKE_CXX_COMPILER clang++.cmd PATH ${COMPILER_PATH})
find_program(CMAKE_AR ${CMAKE_TOOLCHAIN_PREFIX}ar.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_RANLIB ${CMAKE_TOOLCHAIN_PREFIX}ranlib.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_LINKER ${CMAKE_TOOLCHAIN_PREFIX}ld.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_NM ${CMAKE_TOOLCHAIN_PREFIX}nm.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_OBJCOPY ${CMAKE_TOOLCHAIN_PREFIX}objcopy.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_OBJDUMP ${CMAKE_TOOLCHAIN_PREFIX}objdump.exe PATHS ${COMPILER_PATH})
find_program(CMAKE_STRIP ${CMAKE_TOOLCHAIN_PREFIX}strip.exe PATHS ${COMPILER_PATH})

什么不起作用:

请注意,我发现 find_program 是找到这些工具的唯一解决方法,因为例如以下内容将不起作用:

SET(CMAKE_AR ${COMPILER_PATH}/${CMAKE_TOOLCHAIN_PREFIX}ar.exe

(归档操作会失败,我从cmake-gui中可以看到变量没有设置)。

好消息是 Android NDK 支持在最新的 CMake 3.7 版本中变得更加容易。参见 Kitware Increases Android Support in CMake 3.7 and Cross Compiling for Android

编辑: 我已经成功 运行 使用 CMake 3.7 进行测试(例如,在我的 Windows PC 上安装 ADK 到 root):

toolchain.cmake

set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSROOT "C:/android-ndk-r13b/platforms/android-24/arch-arm64")

并使用例如Ninja makefile 生成器:

> cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -G "Ninja" ..
-- Android: Targeting API '24' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64'
-- Android: Selected GCC toolchain 'aarch64-linux-android-4.9'
-- The C compiler identification is GNU 4.9.0
-- The CXX compiler identification is GNU 4.9.0

通用的简化工具链

我在使用最少的工具链文件方面取得了一些很好的经验,并且通常 - 如果您想专门指定工具路径 - 使用工具链文件中的缓存变量。

请参阅 CMake 文档中的 this minimal example,在您的情况下,它会转化为类似以下内容:

set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER <path_to_my_llvm_directory>/clang.cmd)
set(CMAKE_C_COMPILER_TARGET aarch64-linux-android)
set(CMAKE_CXX_COMPILER <path_to_my_llvm_directory>/clang++.cmd)
set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-android)

请注意,指定 CMAKE_SYSTEM_NAME 对启用交叉编译至关重要。

为什么指定 CMAKE_AR 不起作用

关于您的 CMAKE_AR 问题,请注意 CMake 本身确实使用 find_program() 来查找 ar.exe。由于 find_program() 确实会缓存其结果,因此您还必须预填充 CMAKE_AR 作为缓存变量(请参阅 0013038: cannot set CMAKE_AR when cross-compiling Fortran-only project)。