使用 cmake 构建工具链以针对 android 进行交叉编译

Posted

技术标签:

【中文标题】使用 cmake 构建工具链以针对 android 进行交叉编译【英文标题】:Building a toolchain with cmake to cross-compile for android 【发布时间】:2013-10-21 01:09:33 【问题描述】:
gcc (GCC) 4.8.1 
android-ndk-r9 

你好,

我的主机是Fedora 19,我想创建一个工具链来编译程序以在android上运行,稍后我想为ios扩展它。

我收到以下错误:

Check for working C compiler: /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -- broken

我不确定为什么会收到此错误,因为所有内容都已安装。我还安装了binutils-arm-linux-gnu。不过,这是我第一次做这种事情,所以我搞混了。

我正在尝试使用 cmake 创建一个工具链文件来 croos-compile 以在 android 设备上运行库。

我已将 android-ndk-r9 安装在以下位置,并带有编译器的路径:

/opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin

arm-linux-androideabi-addr2line
arm-linux-androideabi-ar
arm-linux-androideabi-as
arm-linux-androideabi-c++
arm-linux-androideabi-c++filt
arm-linux-androideabi-cpp
arm-linux-androideabi-elfedit
arm-linux-androideabi-g++
arm-linux-androideabi-gcc
arm-linux-androideabi-gcc-4.8
arm-linux-androideabi-gcc-ar
arm-linux-androideabi-gcc-nm
arm-linux-androideabi-gcc-ranlib
arm-linux-androideabi-gcov
arm-linux-androideabi-gdb
arm-linux-androideabi-gprof
arm-linux-androideabi-ld
arm-linux-androideabi-ld.bfd
arm-linux-androideabi-ld.gold
arm-linux-androideabi-ld.mcld
arm-linux-androideabi-nm
arm-linux-androideabi-objcopy
arm-linux-androideabi-objdump
arm-linux-androideabi-ranlib
arm-linux-androideabi-readelf
arm-linux-androideabi-run
arm-linux-androideabi-size
arm-linux-androideabi-strings
arm-linux-androideabi-strip

我的交叉编译文件是:

include(CMakeForceCompiler)

set(toolchain_path /opt/ndk/toolchains)

# Target system
set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_SYSTEM_VERSION 1)

# Compiler to build for the target
set(CMAKE_C_COMPILER /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc)

set(CMAKE_FIND_ROOT_PATH /opt/ndk/toolchains)

我从我的构建/调试目录运行它,我的工具链位于根目录中。

[ant@localhost debug]$ cmake -DCMAKE_TOOLCHAIN_FILE=arm-eabi-gcc.cmake ../..

输出

-- The C compiler identification is GNU 4.8.0
-- Check for working C compiler: /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
-- Check for working C compiler: /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -- broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler
  "/opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc"
  is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: /home/steve/mobile_progs/linux_pjsip/build/debug/CMakeFiles/CMakeTmp

  Run Build Command:/usr/bin/gmake "cmTryCompileExec379796592/fast"

  /usr/bin/gmake -f CMakeFiles/cmTryCompileExec379796592.dir/build.make
  CMakeFiles/cmTryCompileExec379796592.dir/build

  gmake[1]: Entering directory
  `/home/steve/mobile_progs/linux_pjsip/build/debug/CMakeFiles/CMakeTmp'

  /usr/bin/cmake -E cmake_progress_report
  /home/steve/mobile_progs/linux_pjsip/build/debug/CMakeFiles/CMakeTmp/CMakeFiles
  1

  Building C object
  CMakeFiles/cmTryCompileExec379796592.dir/testCCompiler.c.o

  /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
  -o CMakeFiles/cmTryCompileExec379796592.dir/testCCompiler.c.o -c
  /home/steve/mobile_progs/linux_pjsip/build/debug/CMakeFiles/CMakeTmp/testCCompiler.c

  Linking C executable cmTryCompileExec379796592

  /usr/bin/cmake -E cmake_link_script
  CMakeFiles/cmTryCompileExec379796592.dir/link.txt --verbose=1

  /opt/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
  CMakeFiles/cmTryCompileExec379796592.dir/testCCompiler.c.o -o
  cmTryCompileExec379796592 -rdynamic 

  /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld:
  error: cannot open crtbegin_dynamic.o: No such file or directory


  /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld:
  error: cannot open crtend_android.o: No such file or directory

  /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld:
  error: cannot find -lc

  /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld:
  error: cannot find -ldl

  collect2: error: ld returned 1 exit status

  gmake[1]: *** [cmTryCompileExec379796592] Error 1

  gmake[1]: Leaving directory
  `/home/steve/mobile_progs/linux_pjsip/build/debug/CMakeFiles/CMakeTmp'

  gmake: *** [cmTryCompileExec379796592/fast] Error 2

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:4 (project)

非常感谢,

【问题讨论】:

【参考方案1】:

为什么不试试这个android-cmake。我仍然使用这个脚本,它工作得很好。如果该方法不符合您的需求,您无论如何都可以将其用作灵感:-)。

【讨论】:

【参考方案2】:

我先去这个网站设法解决了这个问题:

http://developer.android.com/tools/sdk/ndk/index.html

有一个使用 NDK 自带的独立工具链的例子。

make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.8

解压到我的 /opt 目录中。

并使用此示例工具链 cmake 文件

# Target system
set(CMAKE_SYSTEM_NAME  Android)

set(CMAKE_SYSTEM_VERSION 1)

# Compiler to build for the target
set(CMAKE_C_COMPILER /opt/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc)
set(CMAKE_CXX_COMPILER /opt/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-g++)

在那之后一切都正常了。但是,我无法解决以前的问题。也许我将一些环境变量错误地设置到了错误的路径。

希望这对其他人有所帮助。

【讨论】:

谢谢这工作正常。不过,将CMAKE_SYSTEM_NAME 设置为 Linux 怎么样——以防某些配置检查检查到这一点?【参考方案3】:

对于ant2009的原始问题,请尝试在.cmake中添加以下行:

SET (CMAKE_C_FLAGS "$CMAKE_C_FLAGS --sysroot=/opt/ndk/platforms/android-23/arch-arm" CACHE STRING "" FORCE)

SET (CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS --sysroot=/opt/ndk/platforms/android-23/arch-arm" CACHE STRING "" FORCE)

【讨论】:

【参考方案4】:

在 2020 年,make-standalone-toolchain.sh 方法已弃用。

这是更新后的CMakeList.txt

set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 24)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)

PROJECT(mylib C)
CMAKE_MINIMUM_REQUIRED(VERSION 3.18.0)

SET( $PROJECT_NAME_CURRENT 1 )
SET( $PROJECT_NAME_REVISION 0 )
SET( $PROJECT_NAME_AGE 0 )
SET(VERSION "$$PROJECT_NAME_CURRENT.$$PROJECT_NAME_REVISION.$$PROJECT_NAME_AGE")


SET(SOURCES foobar.c)
ADD_LIBRARY(mylib SHARED $SOURCES)

注意:对于 ABI arm64-v8a,需要 CMake 3.18 才能正确检测 NDK 工具链,3.10 是 Ubuntu 18.04 中的版本,找不到工具链。

【讨论】:

以上是关于使用 cmake 构建工具链以针对 android 进行交叉编译的主要内容,如果未能解决你的问题,请参考以下文章

Android NDK——必知必会之Android Studio使用CMake构建NDK项目的背后的故事

Android NDK——必知必会之Android Studio使用CMake构建NDK项目的背后的故事

Android NDK——必知必会之Android Studio使用CMake构建NDK项目的背后的故事

项目构建工具CMake、GYP、GN

cmake中QT的错误工具链

Android Studio Cmake & OpenCV3.2环境