【问题标题】:Cmake cross compiling: finding toolsCmake交叉编译:寻找工具
【发布时间】:2017-03-31 00:56:38
【问题描述】:

我正在使用由 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 http://stackoverflow.com/a/7032021/2436175
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 -> 它从我的路径中的其他 mingw 工具链中找到其他一些工具
  • CMAKE_FIND_ROOT_PATH 设置为${COMPILER_PATH}。那时它甚至找不到编译器。我可以通过使用SET(CMAKE_C_COMPILER ${COMPILER_PATH}/clang.cmd)(clang++ 相同)设置编译器来解决这个问题,但它仍然找不到其他工具
  • find_program 尝试各种标志,尤其是ONLY_CMAKE_FIND_ROOT_PATH

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

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

(存档操作将失败,我可以从 cmake-gui 中看到该变量未设置)。

【问题讨论】:

  • ... I can see from cmake-gui that the variable is not set - cmake-gui 仅显示 缓存 变量。您可以使用SET(CMAKE_AR ... CACHE PATH "Archiver")
  • “有没有办法让它更浓缩?”祝你好运。 Cmake 是一个很棒的工具,但语法和语言行为是垃圾。工具包没有用 python 编写,真是太遗憾了(恕我直言):(
  • @RichardHodges 我确实有 python,但要求我所有的同事安装它只是为了能够构建我们的软件不会让我们的生活更轻松。而用python制作一个“完全独立”的程序并非易事。
  • @Tsyvarev 也有例外,比如你设置了CMAKE_C_COMPILER

标签: c++ android-ndk cmake cross-compiling


【解决方案1】:

好消息是最新的 CMake 3.7 版本对 Android NDK 的支持变得更加容易。请参阅Kitware Increases Android Support in CMake 3.7Cross 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)。

【讨论】:

  • CMake 3.7 的发布似乎与我的问题同步:)。感谢您提供这个非常相关的答案,确实找到了设置这些变量的工具,但我找不到说服 CMake 使用 llvm 的方法:即使这还不够:set(CMAKE_C_COMPILER &lt;full path to the compiler&gt; CACHE PATH "C compiler")。在所有情况下,它都会尝试使用独立工具链中可用的 gcc/g++。
  • 在我尝试的特定解决方法中,CMake 会说You have changed variables that require your cache to be deleted. Configure will be re-run and you may have to reset some variables. The following variables have changed: CMAKE_C_COMPILER= &lt;my full path&gt; CMAKE_CXX_COMPILER= &lt;my full path&gt;,与我为变量定义选择的任何顺序无关。
  • @Antonio 我必须使用最新的 ADK 和 CMake 版本运行一些测试,看看我是否可以重现您的问题。我将在今天晚些时候相应地更新我的答案。但我对你收到的最后一条错误消息很熟悉:如果你更改CMAKE_C_COMPILERCMAKE_CXX_COMPILER,你最好再次从一个空的二进制输出目录开始(它或多或少与你将生成器更改为使用)。
  • 我还必须恢复我的 CMake 安装:我的“旧”工具链文件将不再工作!!使用 CMake 3.6.3 一切都很好。可能最好等到他们完善 3.7 版本。
  • 在 3.6.3 上测试:Using SET(CMAKE_C_COMPILER_TARGET aarch64-linux-android)SET(CMAKE_CXX_COMPILER_TARGET aarch64-linux-android) 消除了所有工具的 find_program 命令的必要性!我认为目前这应该是你答案的第一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
  • 2012-06-18
  • 2020-11-16
相关资源
最近更新 更多