前言:
在android ndk 开发中,是经常需要通过cmakelist 来配置 引入库或者编译配置的。这里总结一些常用的cmakelist 中api 语法。
c++库:静态库(.a、.lib)和动态库(.so、.dll),更多详情,请度娘。
#添加 libavcodec-56.so 库
add_library(
avcodec-lib
SHARED
IMPORTED)
set_target_properties( avcodec-lib
PROPERTIES IMPORTED_LOCATION
${distribution_DIR}/${ANDROID_ABI}/libavcodec-56.so)
add_library(): 第一个参数avcodec-lib
是库的别名,第二个参数SHARED
是库类型,这里是动态库。第三个参数IMPORTED
是引入方式,这里是导入,通常是默认这个。
set_target_propeties() 中:第一个参数avcodec-lib
是库的别名 , 第二个参数PROPERTIES IMPORTED_LOCATION
是指定引入方式,这里是本地引入。第三个参数${distribution_DIR}/${ANDROID_ABI}/libavcodec-56.so
是so库的路径。
因此,引入第三方的库使用add_library就要使用set_target_propeties这个组合。
#添加一个名为webp_view的动态库,指定包含 webp_decode.cpp和webp_view.cpp文件。
add_library(webp_view SHARED
webp_decode.cpp
webp_view.cpp)
这种方式是添加c/c++源码文件,这种不需要使用set_target_propeties()去设置路径。第一个参数webp_view
: 是库名字,第二个参数shared
: 是动态库,第三个参数webp_decode.cpp webp_view.cpp
是需要参与编译的源文件。
用于查找使用android ndk 中系统库,比如 打印日志log库。
#查找log库,且重新别名为log-lib
find_library( log-lib log )
第一个参数log-lib : 重新定义log库的别名 ,第二个参数log : 需要使用库的库名。
用于显示的声明一个变量,比如定义一个变量,其地址是根目录下的libwebp 目录。
# web_simple_proj_dir=项目root目录的绝对路径
get_filename_component(WEBP_SAMPLE_PROJ_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
# 设置webp_src_dir(即libwebp的目录地址)= 项目root目录/libwebp
set(WEBP_SRC_DIR ${WEBP_SAMPLE_PROJ_DIR}/libwebp)
也可以设置cmake 中的一些配置:
设置c++ 11的版本:
# 使用c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
设置c 99 的版本:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
更改so库中一些输出路径: 比如输出在在app/src/main下看到jniLibs目录
下
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
当前CMakeList.txt
中的所有目标以及所有在其调用点之后添加的子目录中的所有目标将具有此头文件搜索路径。
#导入ndk 中native_app_glue目录下的头文件
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
格式:target_include_directories(
指定目标tagert 包含的头文件路径。
INTERFACE
:target对应的头文件使用PRIVATE
:target对应的源文件使用PUBLIC
:target对应的头文件、源文件都使用# 为web_view 导入指定的头文件( private 限定是源文件才可以使用导入的头文件)。
target_include_directories(webp_view PRIVATE
${WEBP_SRC_DIR}/examples
${WEBP_SRC_DIR}/src)
ps:如果有不同目录相同名称的头文件会产生影响,所以这里建议针对特定的target进行添加头文件的操作,不要使用include_directories
在linux中c/c++的编译一般都是用gcc来编译的,c/c++编译时会产生.o文件要通过make工具来把这些.o文件链接起来,这样才能得一个可执行程序。所以.so在编译时要把所有库链接起来才能编。
target_link_libraries 是为了关联我们自己的库和一些第三方库或者系统库。把要链接的库别名都写到这里就可以了,如果是系统的库要用这个格式${库的名字},比如:
# 为webp_view 添加各种依赖库
target_link_libraries(webp_view android log m native_app_glue webp)
在实际开发中,项目可能还包含其他子项目(使用一些开源库的源码)的编译,这时需要指定子项目的cmakelist 参与编译。
#调用libwebp module 下 CamkeList.txt
add_subdirectory(${WEBP_SRC_DIR} ${WEBP_SRC_DIR}/build/)
add_subdirectory() 是可以引入多个需要编译的cmakelist 的目录。这里webp_src_dir 在3.set设置变量
中定义好的路径=项目root目录/libwebp。
先看下webp lib库的目录结构:
接着看下app工程 的目录结构:
最后看下app module中完整cmakelist :
# 使用camke 的版本
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
# 定义一个变量web_simple_proj_dir=项目root目录的绝对路径
get_filename_component(WEBP_SAMPLE_PROJ_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
# 设置webp_src_dir(即libwebp的目录地址)= 项目root目录/libwebp
set(WEBP_SRC_DIR ${WEBP_SAMPLE_PROJ_DIR}/libwebp)
# clone the dependency repo.
# git submodule could also be used if this sample does not need
# Android Studio's "Import Android code sample" option
# 若是不存在libwebp module(即不存在libwebp 目录或者libwebp/CMakeLists.txt) ,执行 从谷歌仓库拷贝 libwebp 1.0.0版本 到webp_src_dir的目录下。
# 或者通过AndroidStudio import 导入方式导入libwebp module源码
if ((NOT EXISTS ${WEBP_SRC_DIR}) OR
(NOT EXISTS ${WEBP_SRC_DIR}/CMakeLists.txt))
execute_process(COMMAND git clone -b 1.0.0
https://chromium.googlesource.com/webm/libwebp
libwebp
WORKING_DIRECTORY ${WEBP_SAMPLE_PROJ_DIR}/)
endif()
SET(WEBP_ENABLE_SWAP_16BIT_CSP ON CACHE BOOL
"Enable byte swap for 16 bit colorspaces." FORCE)
#调用libwebp module 下 CamkeList.txt
add_subdirectory(${WEBP_SRC_DIR} ${WEBP_SRC_DIR}/build/)
# build native_app_glue as a static lib
# 导入ndk路径/source/android/native_app_glue 目录下的头文件
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
#添加一个名为native_app_glue的静态库,包含的文件有ndk路径/source/android/native_app_glue.c
add_library(native_app_glue STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
# 使用c99 版本
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
# 使用c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
# Export ANativeActivity_onCreate(),
# Refer to: https://github.com/android-ndk/ndk/issues/381.
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
#添加一个名为webp_view的动态库,指定包含 webp_decode.cpp和webp_view.cpp文件。
add_library(webp_view SHARED
webp_decode.cpp
webp_view.cpp)
# 为web_view 导入指定的头文件( private 限定是源文件才可以使用导入的头文件)。
target_include_directories(webp_view PRIVATE
${WEBP_SRC_DIR}/examples
${WEBP_SRC_DIR}/src)
# 为webp_view 添加各种依赖库
target_link_libraries(webp_view android log m native_app_glue webp)