美文网首页
使用CMake编译Android可执行文件并运行

使用CMake编译Android可执行文件并运行

作者: 晴空一垩 | 来源:发表于2019-07-30 16:09 被阅读0次

本文主要介绍:不建立在AS的基础上,直接使用cmake编译源代码,并运行在模拟器上

虚拟机环境:

  1. debian_9_64
  2. cmake : 3.7.2
  3. ndk : r14b

window环境:

  1. Android模拟器:夜神模拟器
  2. adb 环境

编写一个cpp文件:a.cpp

#include <a.h>
 int main(){
      printf("hello world \n");
     return 0;
 }

a.h

#include<stdio.h>

CMakeLists.txt

如果对cmake的语法不熟悉:可以查看我之前写的文章

cmake_minimum_required(VERSION 3.7)
# 这是我这边ndk的绝对路径,需要改成你们自己的ndk环境
# NDK 已经默认提供了工具链的cmake可供使用
include(/cross/github/jni/android-ndk-r14b/build/cmake/android.toolchain.cmake)

# 打印当前的环境
if(ANDROID)
    message(STATUS "ANDROID")
elseif(APPLE)
    message(STATUS "APPLE")
elseif(WIN32)
    message(STATUS "WIN32")
elseif(UNIX)
    message(STATUS "UNIX")
else()
    message(FATAL_ERROR "OTHER")
endif()
 
add_executable(t a.cpp)
target_include_directories(t PRIVATE .)

再新建一个build目录,来进行编译

cmake ..

# 输出,建立MakeFile成功,平台为Android平台
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- ANDROID_C_COMPILER:/cross/github/jni/android-ndk-r14b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
-- ANDROID_CXX_COMPILER:/cross/github/jni/android-ndk-r14b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
-- ANDROID # 这里可以看到为Android平台
-- Configuring done
-- Generating done
-- Build files have been written to: /home/txz/test/testCmake/t12/build

执行编译

make VERBOSE=1

# 输出 unknown target CPU 'armv7-a'
/usr/bin/cmake -H/home/txz/test/testCmake/t12 -B/home/txz/test/testCmake/t12/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/txz/test/testCmake/t12/build/CMakeFiles /home/txz/test/testCmake/t12/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/txz/test/testCmake/t12/build'
make -f CMakeFiles/t.dir/build.make CMakeFiles/t.dir/depend
make[2]: Entering directory '/home/txz/test/testCmake/t12/build'
cd /home/txz/test/testCmake/t12/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/txz/test/testCmake/t12 /home/txz/test/testCmake/t12 /home/txz/test/testCmake/t12/build /home/txz/test/testCmake/t12/build /home/txz/test/testCmake/t12/build/CMakeFiles/t.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/txz/test/testCmake/t12/build'
make -f CMakeFiles/t.dir/build.make CMakeFiles/t.dir/build
make[2]: Entering directory '/home/txz/test/testCmake/t12/build'
[ 50%] Building CXX object CMakeFiles/t.dir/a.cpp.o
/cross/github/jni/android-ndk-r14b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  --sysroot=/cross/github/jni/android-ndk-r14b/platforms/android-9/arch-arm   -isystem /cross/github/jni/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/include -isystem /cross/github/jni/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -isystem /cross/github/jni/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/include/backward  -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security     -fPIC -fPIE -o CMakeFiles/t.dir/a.cpp.o -c /home/txz/test/testCmake/t12/a.cpp
clang++: warning: argument unused during compilation: '-mfloat-abi=softfp'
clang++: warning: argument unused during compilation: '-mfpu=vfpv3-d16'
clang++: warning: argument unused during compilation: '-mthumb'
error: unknown target CPU 'armv7-a'
CMakeFiles/t.dir/build.make:62: recipe for target 'CMakeFiles/t.dir/a.cpp.o' failed
make[2]: *** [CMakeFiles/t.dir/a.cpp.o] Error 1
make[2]: Leaving directory '/home/txz/test/testCmake/t12/build'
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/t.dir/all' failed
make[1]: *** [CMakeFiles/t.dir/all] Error 2
make[1]: Leaving directory '/home/txz/test/testCmake/t12/build'
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

经过google,尝试,我们应该

修改CMakeLists.txt

cmake_minimum_required(VERSION 3.7)
# 去掉include 
# 打印平台可以继续保留
add_executable(t a.cpp)
target_include_directories(t PRIVATE .)

编译指令也需要修改

cmake  -DCMAKE_TOOLCHAIN_FILE=/cross/github/jni/android-ndk-r14b/build/cmake/android.toolchain.cmake ..

# 输出,这时候又报一堆的错误。
CMake Error at /usr/share/cmake-3.7/Modules/CMakeTestCCompiler.cmake:51 (message):
  The C compiler
  "/cross/github/jni/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/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/txz/test/testCmake/t12/build/CMakeFiles/CMakeTmp

  

  Run Build Command:"/usr/bin/make" "cmTC_314c6/fast"

  /usr/bin/make -f CMakeFiles/cmTC_314c6.dir/build.make
  CMakeFiles/cmTC_314c6.dir/build

  make[1]: Entering directory
  '/home/txz/test/testCmake/t12/build/CMakeFiles/CMakeTmp'

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

  
  /cross/github/jni/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
  --target=armv7-none-linux-androideabi --gcc-toolchain=""
  --sysroot=/cross/github/jni/android-ndk-r14b/platforms/android-9/arch-arm
  -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong
  -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
  -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat
  -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables
  -fstack-protector-strong -no-canonical-prefixes -march=armv7-a
  -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb
  -Wa,--noexecstack -Wformat -Werror=format-security -O0
  -fno-limit-debug-info -o CMakeFiles/cmTC_314c6.dir/testCCompiler.c.o -c
  /home/txz/test/testCmake/t12/build/CMakeFiles/CMakeTmp/testCCompiler.c

  arm-linux-androideabi-gcc: error: unrecognized command line option
  '--gcc-toolchain='

  arm-linux-androideabi-gcc: error: unrecognized command line option
  '-fno-integrated-as'

  arm-linux-androideabi-gcc: error: unrecognized command line option
  '-fno-integrated-as'

  arm-linux-androideabi-gcc: error: unrecognized command line option
  '-fno-limit-debug-info'

  CMakeFiles/cmTC_314c6.dir/build.make:65: recipe for target
  'CMakeFiles/cmTC_314c6.dir/testCCompiler.c.o' failed

  make[1]: *** [CMakeFiles/cmTC_314c6.dir/testCCompiler.c.o] Error 1

  make[1]: Leaving directory
  '/home/txz/test/testCmake/t12/build/CMakeFiles/CMakeTmp'

  Makefile:126: recipe for target 'cmTC_314c6/fast' failed

  make: *** [cmTC_314c6/fast] Error 2

google之后,发现需要使用clang,那么怎样才能制定clang呢?手动制定C/C++的编译器?【不行】

这时候只能细看android.toolchain.cmake 这个文件了,终于发现是要增加-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang 这个参数才可以

最终的编译参数是:

cmake  -DCMAKE_TOOLCHAIN_FILE=/cross/github/jni/android-ndk-r14b/build/cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN=clang -DANDROID_ABI=armeabi-v7a -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang   ..
# 输出就很正常了

make VERBOSE=1 
# 会发现输出了你想要的东西

运行模拟器,因为我是一个Android开发,所以这里比较熟悉

adb connect 127.0.0.1:62001 # 链接夜神模拟器

这里有一点一定要说下:必须要把文件放到/data目录底下,最好放置在/data/local/tmp,否则你修改不了权限,就不能够运行,好像是Android系统会限制其他目录的可执行权限吧。

adb push G:\shareLinux\t /data/local/tmp # 将文件放到模拟器里面
adb shell           #进入模拟器
cd /data/local/tmp  # 进入模拟器里面的指定目录
chmod 777 t         # 修改权限
./t                 # 执行
# 输出
hello world

如果执行的时候会报需要position independent executables 则需要再CMakeLists.txt中指定参数

add_definitions("-fPIC -fPIE")

至此,使用cmake编译并运行成功

相关文章

网友评论

      本文标题:使用CMake编译Android可执行文件并运行

      本文链接:https://www.haomeiwen.com/subject/bopnrctx.html