2016-11-16 208 views
0

我正在使用由android ndk13b制作的独立工具链。它工作正常,但找到所有的工具(链接器,存档等)我有一个非常详细的部分在我的工具链文件。 有没有办法让它更浓缩?Cmake交叉编译:查找工具

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)设置编译器,而不是(同为铛++),但它仍然没有找到其他工具
  • 尝试各种标志与find_program,尤其是ONLY_CMAKE_FIND_ROOT_PATH

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

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

(归档操作将失败,我可以从该变量没有设置cmake的桂见)。

+0

'...我可以从cmake的桂该变量不set'看 - 'cmake的-gui'只显示*高速缓存*变量。您可以使用'SET(CMAKE_AR ... CACHE PATH“Archiver”)'。 – Tsyvarev

+0

“有没有办法让它更浓缩?”祝你好运。 Cmake是一个很棒的工具,但是语法和语言行为是垃圾。这是一个真正的耻辱(恕我直言)是kitware没有把它用Python语言编写:( –

+0

@RichardHodges我有蟒蛇,但要求全体同仁来安装它只是为了能够建立我们的软件不会使我们的生活更轻松。并作出“完全独立”的计划了蟒蛇是不平凡的。 – Antonio

回答

2

好的新功能是,使用最新的CMake 3.7版本,Android NDK支持变得更容易。请参阅Kitware Increases Android Support in CMake 3.7Cross Compiling for Android

编辑:我已经成功地运行与CMake的3.7测试(例如安装ADK铲除我的Windows PC上):

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 

简体工具链一般

我已经取得了一些好经验以最小的工具链文件和一般 - 如果要指定专门的刀具路径 - 使用缓存的变量工具链文件。

this minimal example从CMake的文档,这将翻译你的情况到是这样的:

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)。

+0

CMake的3.7的版本似乎与我的问题:)同步。感谢您对这个非常相关的答案,设置工具确实发现了这些变量,但我无法找到一个方法来说服CMake的使用LLVM:即使这是不够的:'设置(CMAKE_C_COMPILER <完整路径编译器>缓存路径“C编译“)'。在所有情况下,它都会尝试使用独立工具链中可用的gcc/g ++。 – Antonio

+0

在具体解决方法我试过,CMake的会说'你已经改变了,需要你的缓存中删除变量。 配置将重新运行,您可能需要重置一些变量。 以下变量发生了变化: CMAKE_C_COMPILER = <我的完整路径> CMAKE_CXX_COMPILER = <我的完整路径>',独立于任何订单,我选择的变量定义。 – Antonio

+0

@Antonio我已经运行一些测试了最新的ADK和CMake的版本,看看是否我可以重现你的问题。我会在今天晚些时候更新我的答案。但我熟悉你的最后一条错误消息:如果你改变'CMAKE_C_COMPILER'或'CMAKE_CXX_COMPILER'您再次空二进制输出目录最好的开始(这是或多或少相同的,如果你会改变发电机是用过的)。 – Florian