Android Studio 嵌套使用CMakeLists.txt

Android Studio新版使用了CMakeLists.txt来管理c/cpp文件,现在就不用写Android.mk来进行编译了。事实感觉cmake的语法更简洁易用,或许这也是谷歌采用的原因之一。
这里简单贴一些用法,复杂用法请参考官方文档https://cmake.org/cmake/help/v3.10/

语法

  1. “#”注释

  2. 变量:使用set命令显式定义及赋值,在非if语句中,使用${}引用,if中直接使用变量名引用;后续的set命令会清理变量原来的值;

  3. command (args …) #命令不分大小写,参数使用空格分隔,使用双引号引起参数中空格

  4. set(var a;b;c) <=> set(var a b c) #定义变量var并赋值为a;b;c这样一个string list

  5. Add_executable(${var}) <=> Add_executable(a b c) #变量使用${xxx}引用

  6. 条件语句:

if(var) #var 非empty 0 N No OFF FALSE… #非运算使用NOT

else()/elseif() … endif(var)

  1. 循环语句

Set(VAR a b c)

Foreach(f ${VAR}) …Endforeach(f)

  1. 循环语句

WHILE() … ENDWHILE()

内部变量

CMAKE_C_COMPILER:指定C编译器

CMAKE_CXX_COMPILER:

CMAKE_C_FLAGS:编译C文件时的选项,如-g;也可以通过add_definitions添加编译选项

EXECUTABLE_OUTPUT_PATH:可执行文件的存放路径

LIBRARY_OUTPUT_PATH:库文件路径

CMAKE_BUILD_TYPE::build 类型(Debug, Release, …),CMAKE_BUILD_TYPE=Debug

BUILD_SHARED_LIBS:Switch between shared and static libraries

命令

project (HELLO) #指定项目名称,生成的VC项目的名称;

使用${HELLO_SOURCE_DIR}表示项目根目录

include_directories:指定头文件的搜索路径,相当于指定gcc的-I参数

include_directories (${HELLO_SOURCE_DIR}/Hello) #增加Hello为include目录

link_directories:动态链接库或静态链接库的搜索路径,相当于gcc的-L参数

   >> link_directories (${HELLO_BINARY_DIR}/Hello)     #增加Hello为link目录

add_subdirectory:包含子目录

   >> add_subdirectory (Hello)

add_executable:编译可执行程序,指定编译,好像也可以添加.o文件

   >> add_executable (helloDemo demo.cxx demo_b.cxx)   #将cxx编译成可执行文件——

add_definitions:添加编译参数

add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义;

target_link_libraries:添加链接库,相同于指定-l参数

target_link_libraries(demo Hello) #将可执行文件与Hello连接成最终文件demo

add_library:

add_library(Hello hello.cxx) #将hello.cxx编译成静态库如libHello.a

add_custom_target:
打印消息
message( status|fatal_error, “message”):
在指定目录下搜索一个库, 保存在变量MY_LIB中
find_ibrary(MY_LIB libmylib.a ./)
set_target_properties( … ): lots of properties… OUTPUT_NAME, VERSION, ….

link_libraries( lib1 lib2 …): All targets link with the same set of libs

现在使用Android Studio使用一下CMake,使用lame库将pcm编码生成Mp3文件。Android Studio如何配置CMake我就不细说了,如果还不太明白NDK开发流程的,建议先了解一下,后面可以参照源码配置。
项目结构
Android Studio 嵌套使用CMakeLists.txt_第1张图片
简单说明一下:
mp3_encoder.cpp 直接封装lame的功能;
audio_encoder.cpp 用来和java层对接,调用mp3_encoder.cpp;
test.cpp 纯属测试
我们先来看最外层的CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__STDC_CONSTANT_MACROS") #设置C文件的编译参数
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")#设置cpp文件的编译参数
#add_compile_options(-std=c++11) #设置编译参数,包括上面两者

include_directories(libs/include)#包含.h文件include目录


add_subdirectory(src/main/cpp/libmp3_endocer)#添加下级目录,下级目录需包含CMakeLists.txt
add_subdirectory(src/main/cpp/test)

#添加cpp编译文件 这里会编译出来libaudio_encoider.so
add_library( audio_encoder
             SHARED
             src/main/cpp/audio_encoder.cpp )

#链接库
target_link_libraries(
                       audio_encoder
                       log#native 日志
                        mp3_encoder# mp3编码核心
                        tts#测试用
                        )

接下来是libmp3_endocer下的CMakeLists.txt


#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_CONFIG_H -DFPM_ARM -ffast-math -O3"  )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CONFIG_H -DFPM_ARM -ffast-math -O3")

set(distribution_DIR ../../../../libs)#内层或者外层都是四个点,这里应该是某个编译的路径计算

add_library( mp3_encoder
             STATIC
             mp3_encoder.cpp )

#这里导入外部库 静态库.a
add_library( mp3lame
             STATIC
             IMPORTED)

set_target_properties(mp3lame
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/armeabi-v7a/libmp3lame.a)

target_link_libraries(
                       mp3_encoder
                       mp3lame
                        )

test下的CMakeLists.txt


#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLOGTEST")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLOGTEST")

add_library( tts
             SHARED
             test.cpp )

target_link_libraries(
                       tts
                       log
                        )

其实结构比较简单,直接编译就会生成带有两个.so的apk
Android Studio 嵌套使用CMakeLists.txt_第2张图片
这两个.so包含

最外层的CMakeList.txt和test目录下的CMakeList.txt生成的,至于libmp3_endocer这个目录的add_library是使用的STATIC,所以直接链接到目标代码中的,不会生成so。所以要生成多个so也就可以参照test目录下的方式来写。
至于CMAKE_C_FLAG这个编译选项我想说明一下的是,实际测试各自目录FLAG对各自目录的有效,顶层的CMakeList.txt对下面所有文件有效。注意C文件和CPP文件是不同的FLAG。

这个项目的功能是使用lame库将PCM编码成MP3文件,需要实验的将根目录下的vocal.pcm放到手机指定的目录下,具体路径可以参照MainActivity。
源码下载

你可能感兴趣的:(CMakeList)