解决什么问题:
很多make工具有不同饭标准和规范,不支持跨平台,如果想跨平台就的为每个平台都写一份makefile,cmake就是用来可以跨平台的编译工具
使用步骤:
1.编写Cmakelist.txt
2.执行make PATH生成Makefile
3.使用make命令进行编译
安装:
编译源码
下载二进制文件
命令行操作需要:
CMAKE常用语法:
//指定最小支持的Cmake版本
cmake_minimum_required(VERSION 3.4.1)
./Demo3
|
±-- main.cc
|
±-- math/
|
±-- MathFunctions.cc
|
+— MathFunctions.h
cmake_minimum_required (VERSION 2.8)
project (Demo3)
aux_source_directory(. DIR_SRCS)
add_subdirectory(math)
add_executable(Demo main.cc)
target_link_libraries(Demo MathFunctions)
aux_source_directory(. DIR_LIB_SRCS)
add_library (MathFunctions ${DIR_LIB_SRCS})
//指定头文件路径
include_directories(src/main/cpp/include/)
//调用系统日志库,并将其路径存储为log-lib变量
find_library(log-lib log )
//链接静态库
add_library( app-glue
STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
链接动态库
add_library(swscale4 SHARED IMPORTED)
set_target_properties( swscale4
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libswscale4.so)
//链接库,最后进行关联
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )
变量:
CMAKE_SOURCE_DIR:工程的顶层目录
CMAKE_CURRENT_SOURCE_DIR:当前Cmakelist文件所在的目录
//保存变量
set(BREAKPAD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
//GLOB 搜集文件,保存到变量中
file(GLOB BREAKPAD_SOURCES_COMMON
a.txt b.txt)
add_library(native-lib STATIC ${BREAKPAD_SOURCES_COMMON})
//设置编译器选项
set(CMAKE_C_FLAGS “KaTeX parse error: Double subscript at position 9: {CMAKE_C_̲FLAGS} -Wall -O…{CMAKE_CXX_FLAGS} -Wall -O3 -march=native -Wno-reorder”)
//build.gradle的配置
android {
defaultConfig {
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters 'armeabi'//, "x86"
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
例如ffmpeg的cmake编写:
cmake_minimum_required(VERSION 3.4.1)
include_directories(src/main/cpp/include)
#使用C文件生成so
add_library(player SHARED
src/main/cpp/player.cpp
src/main/cpp/CallJava.cpp
src/main/cpp/AudioPlayer.cpp
src/main/cpp/AvPacketQueue.cpp
src/main/cpp/FfmpegPlayer.cpp
src/main/cpp/PlayStatus.cpp
)
#调用系统日志库
find_library(log-lib log )
add_library(avcodec57 SHARED IMPORTED)
set_target_properties( avcodec57
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libavcodec57.so)
add_library(avdevice57 SHARED IMPORTED)
set_target_properties( avdevice57
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libavdevice57.so)
add_library(avfilter6 SHARED IMPORTED)
set_target_properties( avfilter6
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libavfilter6.so)
add_library(avformat57 SHARED IMPORTED)
set_target_properties( avformat57
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libavformat57.so)
add_library(avutil55 SHARED IMPORTED)
set_target_properties( avutil55
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libavutil55.so)
add_library(postproc54 SHARED IMPORTED)
set_target_properties( postproc54
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libpostproc54.so)
add_library(swresample2 SHARED IMPORTED)
set_target_properties( swresample2
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libswresample2.so)
add_library(swscale4 SHARED IMPORTED)
set_target_properties( swscale4
PROPERTIES IMPORTED_LOCATION
C M A K E S O U R C E D I R / s r c / m a i n / j n i L i b s / {CMAKE_SOURCE_DIR}/src/main/jniLibs/ CMAKESOURCEDIR/src/main/jniLibs/{ANDROID_ABI}/libswscale4.so)
#连接动态库
target_link_libraries( # Specifies the target library.
player
avcodec57
avdevice57
avfilter6
avformat57
avutil55
postproc54
swresample2
swscale4
OpenSLES
# Links the target library to the log library
# included in the NDK.
log )
NDK build自定义名字的mk:
ndk-build NDK_APPLICATION_MK=./MyApplication.mk
MK加打印信息
( i n f o L O C A L P A T H = (info LOCAL_PATH= (infoLOCALPATH=(LOCAL_PATH))
打印编译信息:
ndk-build V=1
制作独立工具链:
./make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=/Users/chenhong/android-ndk/ --stl=libc++ —force
编译main.cpp:
/Users/chenhong/android-ndk/bin/arm-linux-androideabi-clang++ -o main main.cpp wpa_ctrl.cpp -pie -fPIE
Clang 比 GCC 编译器的优势:
编译速度更快
编译产出更小
出错提示更友 好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 “ 认为 ” 正确的方式 。
内置有静态分析工具,可以对代码进行静态分析 (clang—analyze) 。这也是 gcc 做不到的 。
专注
常见错误:
/Users/chen/Android/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++
is not a full path to an existing compiler tool.
The CMAKE_CXX_COMPILER:
/Users/chenhong/Android/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++
解决:
进入对应目录发现确实没有该文件,工具链被损坏了,重现下载一个就OK了!