本文主要介绍:不建立在AS的基础上,直接使用cmake编译源代码,并运行在模拟器上
虚拟机环境:
- debian_9_64
- cmake : 3.7.2
- ndk : r14b
window环境:
- Android模拟器:夜神模拟器
- 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编译并运行成功
网友评论