一、Cmake語法詳解
1捏萍、什么是CMake
- 在Android Studio 2.2及以上,構(gòu)建原生庫的默認(rèn)工具是
CMake
旷余。 - CMake是一個跨平臺的構(gòu)建工具,可以用簡單的語句來描述所有平臺的安裝(編譯過程)扁达。能夠輸出各種各樣的makefile或者project文件正卧。CMake并不直接構(gòu)建出最終的軟件,而是產(chǎn)生其他工具的腳本(如makefile)跪解,然后再依據(jù)這個工具的構(gòu)建方式使用炉旷。
- CMake是一個比make更高級的編譯配置工具,它可以根據(jù)不同的平臺叉讥、不同的編譯器窘行,生成相應(yīng)的makefile或vcproj項目,從而達到跨平臺的目的图仓。Android Studio利用CMake生成的是ninja罐盔。ninja是一個小型的關(guān)注速度的構(gòu)建系統(tǒng)。我們不需要關(guān)心ninja的腳本救崔,知道怎么配置CMake就可以了惶看。
- CMake其實是一個跨平臺的支持產(chǎn)出各種不同的構(gòu)建腳本的一個工具。
2六孵、CMake源文件
- CMake的源碼文件可以包含命令纬黎、注釋、空格和換行劫窒。
- 以CMake編寫的源文件以CmakeLists.txt命名或以.cmake為擴展名莹桅。
- 可以通過
add_subdirectory()
命令把子目錄的CMake源文件添加進來。 - CMake源文件中所有有效的語句都是命令烛亦,可以是內(nèi)置命令或自定義的函數(shù)/宏命令诈泼。
3、CMake注釋
# 單行注釋
#[[多行注釋
多行注釋
多行注釋]]
復(fù)制代碼
- 單行注釋:#注釋內(nèi)容(注釋從#開始到行尾結(jié)束)
- 釣竿注釋:可以使用括號來實現(xiàn)多行注釋:#[[多行注釋]]
4煤禽、CMake變量
# 聲明變量:set(變量名 變量值)
set(var 123)
# 引用變量:message 命令用來打印
message("var = ${var}")
復(fù)制代碼
- CMake中所有變量都是string類型铐达。可以使用
set()
和unset()
命令來聲明或移除一個變量 - 變量的引用:
${變量名}
5檬果、CMake列表(lists)
# 聲明列表:set(列表名 值1 值2 ... 值N)
# 或set(列表名 "值1;值2;...;值N")
set(list_var 1 2 3 4 5)
# 或者
set(list_var2 "1;2;3;4;5")
message("list_var = ${list_var}")
復(fù)制代碼
- 列表也是字符串瓮孙,可以把列表看作一個特殊的變量,這個變量有多個值选脊。
- 語法格式:
set(列表名 值1 值2 ... 值N)
杭抠、set(列表名 "值1;值2;...;值N")
- 列表的引用:
${列表名}
6、CMake流程控制-操作符
類型 | 名稱 |
---|---|
一元 | EXIST,COMMAND,DEFINED |
二元 | EQUAL,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL,STREQUAL,STRLESS, |
STRLESS_EQUAL,STRGREATER,STRGREATER_EQUAL,VERSION_EQUAL,VERSION_LESS,
VERSION_LESS_EQUAL,VERSION_GREATER,VERSION_GREATER_EQUAL,MATCHES |
| 邏輯 | NOT,AND,OR |
7恳啥、CMake流程控制-布爾常量值
類型 | 值 |
---|---|
true | 1,ON,YES,TRUE,Y,非0的值 |
false | 0,OFF,NO,FALSE,N,IGNORE,NOTFOUND,空字符串偏灿, |
以-NOTFOUND結(jié)尾的字符串 |
8、CMake流程控制-條件命令
set(if_tap OFF)
set(elseif_tap ON)
if(${if_tap})
message("if")
elseif(${elseif_tap})
message("elseif")
else(${if_tap})
message("else")
endif(${if_tap})
復(fù)制代碼
- 語法格式:
if(表達式)
COMMAND(ARGS...)
elseif(表達式)
COMMAND(ARGS...)
else(表達式)
COMMAND(ARGS...)
endif(表達式)
復(fù)制代碼
- elseif和else部分是可選的钝的,也可以有多個elseif部分翁垂,縮進和空格對語句解析沒有影響铆遭。
9、CMake流程控制-循環(huán)命令
set(a "")
while(NOT a STREQUAL "xxx")
set(a "${a}x")
message("a = ${a}")
endwhile()
復(fù)制代碼
- 語法格式:
while(表達式)
COMMAND(ARGS...)
endwhile(表達式)
復(fù)制代碼
- break()命令可以跳出整個循環(huán)沿猜。
- continue()可以跳出當(dāng)前循環(huán)枚荣。
10、CMake流程控制-循環(huán)遍歷
1)格式一
foreach(item 1 2 3)
message("item = ${item}")
endforeach(item)
復(fù)制代碼
- 語法格式:
foreach(循環(huán)變量 參數(shù)1 參數(shù)2 ... 參數(shù)N)
COMMAND(ARGS...)
endforeach(循環(huán)變量)
復(fù)制代碼
- 每次迭代設(shè)置循環(huán)變量為參數(shù)啼肩。
- foreach也支持break()和continue()命令跳出循環(huán)橄妆。
2)格式二
foreach(item RANGE 3)
message("item = ${item}")
endforeach(item)
復(fù)制代碼
- 語法格式:
foreach(循環(huán)變量 RANGE total)
COMMAND(ARGS...)
endforeach(循環(huán)變量)
復(fù)制代碼
- 循環(huán)范圍從0到total。
3)格式三
foreach(item RANGE 1 5 2)
message("item = ${item}")
endforeach(item)
復(fù)制代碼
- 語法格式:
foreach(循環(huán)變量 RANGE start stop step)
COMMAND(ARGS...)
endforeach(循環(huán)變量)
復(fù)制代碼
- 循環(huán)范圍從start到stop祈坠,循環(huán)增量為step呼畸。
4)格式四
set(list_var 1 2 3)
foreach(item IN LISTS list_var)
message("item = ${item}")
endforeach(item)
復(fù)制代碼
- foreach還支持對列表的循環(huán)。
- 語法格式:
foreach(循環(huán)變量 IN LISTS 列表)
COMMAND(ARGS...)
endforeach(循環(huán)變量)
復(fù)制代碼
11颁虐、CMake自定義函數(shù)命令
function(func x y z)
message("call function func")
message("x = ${x}")
message("y = ${y}")
message("z = ${z}")
message("ARGC = ${ARGC}")
message("arg1 = ${ARGV0} arg2 = ${ARGV1} arg3 = ${ARGV2}")
message("all args = ${ARGV}")
endfunction(func)
func(1 2 3)
復(fù)制代碼
ARGC
:表示傳入?yún)?shù)的個數(shù)蛮原。ARGV
:表示所有參數(shù)。ARGV0
:表示第一個參數(shù)另绩,ARGV1
儒陨、ARGV2
以此類推。
- 自定義函數(shù)命令格式:
function(<name> [arg1[arg2[arg3...]]])
COMMAND()
endfunction(<name>)
復(fù)制代碼
- 函數(shù)命令調(diào)用格式:
name(實參列表)
12笋籽、CMake自定義宏命令
macro(ma x y z)
message("call macro ma")
message("x = ${x}")
message("y = ${y}")
message("z = ${z}")
endmacro(ma)
ma(1 2 3)
復(fù)制代碼
函數(shù)命令有自己的作用域蹦漠。 宏命令跟調(diào)用者的作用域一樣。
- 自定義宏命令格式:
macro(<name> [arg1[arg2[arg3...]]])
COMMAND()
endmacro(<name>)
復(fù)制代碼
- 宏命令調(diào)用格式:
name(實參列表)
13车海、CMake變量的作用域
-
全局層
:cache變量笛园,在整個項目范圍可見,一般在set定義變量時侍芝,指定CACHE參數(shù)就能定義cache變量研铆。 -
目錄層
:在當(dāng)前目錄CMakeLists.txt中定義,以及在該文件包含的其他cmake源文件中定義的變量州叠。 -
函數(shù)層
:在命令函數(shù)中定義的變量棵红,屬于函數(shù)作用域內(nèi)的變量。
變量查找優(yōu)先級:
函數(shù)層
優(yōu)于目錄層
咧栗,目錄層
優(yōu)于全局層
逆甜,即:函數(shù)層
-->目錄層
-->全局層
二、CMakeList.txt文件詳解
1致板、CMakeLists.txt簡析
使用AndroidStudio3.4創(chuàng)建一個C/C++Support的項目交煞,默認(rèn)在app/src/main目錄下會生成cpp目錄,里面包含CMakeLists.txt和native-lib.cpp斟或。以下代碼為CMakeLists.txt去掉英文注釋格式化后的內(nèi)容:
cmake_minimum_required(VERSION 3.4.1)
# 添加一個庫素征,根據(jù)native-lib.cpp源文件編譯一個native-lib的動態(tài)庫
add_library(
native-lib
SHARED
native-lib.cpp)
# 查找系統(tǒng)庫,這里查找的是系統(tǒng)日志庫,并賦值給變量log-lib
find_library(
log-lib
log)
# 設(shè)置依賴的庫(第一個參數(shù)必須為目標(biāo)模塊稚茅,順序不能換)
target_link_libraries(
native-lib
${log-lib})
復(fù)制代碼
-
cmake_minimum_required
:指定cmake最低支持的版本。這個命令是可選的平斩,如果在CMakeLists.txt文件中使用了高版本特有的命令的話亚享,就需要加上這條命令,來指定CMake的最低支持版本绘面,如果CMake當(dāng)前版本低于我們指定的版本就會報錯欺税。 -
aux_source_directory(. DIR_SRCS)
:查找當(dāng)前目錄所有源文件,并將源文件名稱列表保存到DIR_SRCS
變量揭璃;但不能查找子目錄中的源文件晚凿。 -
find_library
:查找系統(tǒng)庫,默認(rèn)會在AndroidNDK目錄\platforms\android-xx\arch-arm\usr\lib
下查找瘦馍。
2歼秽、常用命令-add_library
1)添加一個庫
- 添加一個庫文件,名為
<name>
情组。 - 指定STATIC燥筷,SHARED,MODULE參數(shù)來指定庫的類型院崇。STATIC:靜態(tài)庫肆氓,SHARED:動態(tài)庫,MODULE:在使用dyld的系統(tǒng)有效底瓣,若不支持dyld谢揪,等同于SHARED。
- EXCLUDE_FROM_ALL:表示該庫不會被默認(rèn)構(gòu)建捐凭。
- source1 source2 ... sourceN:用來指定庫的源文件拨扶。
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
復(fù)制代碼
2)導(dǎo)入預(yù)編譯庫
- 添加一個已存在的預(yù)編譯庫,名為
<name>
茁肠。 - 一般配合set_target_properties使用屈雄。
add_library(<name> <SHARED|STATIC|MODULE|UNKNOW> IMPORTED)
# 比如
add_library(test SHARED IMPORTED)
set_target_properties(
test # 指明目標(biāo)庫名
PROPERTIES IMPORTED_LOCATION # 指明要設(shè)置的參數(shù)
庫路徑/${ANDROID_ABI}/libtest.so # 導(dǎo)入庫的路徑
)
復(fù)制代碼
3、常用命令-set
設(shè)置CMake變量:
# 設(shè)置可執(zhí)行文件的輸出路徑(EXECUTABLE_OUTPUT_PATH是全局變量)
set(EXECUTABLE_OUTPUT_PATH [output_path])
# 設(shè)置庫文件的輸出路徑(LIBRARY_OUTPUT_PATH是全局變量)
set(LIBRARY_OUTPUT_PATH [output_path])
# 設(shè)置C++編譯參數(shù)(CMAKE_CXX_FLAGS是全局變量)
set(CMAKE_CXX_FLAGS "-Wall std=c++11")
# 設(shè)置源文件集合(SOURCE_FILES是本地變量即自定義變量)
set(SOURCE_FILES main.cpp test.cpp ...)
復(fù)制代碼
4官套、常用命令-include_directories
設(shè)置頭文件目錄酒奶。
# 可以用相對或絕對路徑,也可以用自定義的變量值
include_directories(./include ${MY_INCLUDE})
復(fù)制代碼
相當(dāng)于g++選項中的-l參數(shù)奶赔。
5惋嚎、常用命令-add_executable
添加可執(zhí)行文件:
add_executable(<name> ${SRC_LIST})
復(fù)制代碼
6、常用命令-target_link_libraries
target_link_libraries(<name> lib1 lib2 lib3)
# 如果出現(xiàn)互相依賴的靜態(tài)庫站刑,CMake會允許依賴圖中包含循環(huán)依賴另伍,如:
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)
復(fù)制代碼
- 將若干庫鏈接到目標(biāo)庫文件。
- 鏈接的順序應(yīng)當(dāng)符合gcc鏈接順序規(guī)則,被鏈接的庫放在依賴它的庫的后面摆尝,即如果上面的命令中温艇,lib1依賴于lib2,lib2又依賴于lib3堕汞,則在上面命令中必須嚴(yán)格按照lib1 lib2 lib3的順序排列勺爱,否則會報錯。
7讯检、常用命令-add_definitions
為當(dāng)前路徑以及子目錄的源文件加入由-D引入的define flag
add_definitions(-DF00 -DDEBUG ...)
復(fù)制代碼
通常用于添加編譯參數(shù)
8琐鲁、常用命令-add_subdirectory
用于添加子目錄的CMake源文件:
# sub_dir指定包含CMakeLists.txt和源碼文件的子目錄位置
# binary_dir是輸出路徑,一般可以不指定
add_subdirectory(sub_dir [binary_dir])
復(fù)制代碼
如果當(dāng)前目錄下還有子目錄時可以使用add_subdirectory人灼,子目錄中也需要包含有CMakeLists.txt围段。
9、常用命令-file
文件操作命令:
# 將message寫入filename文件中投放,會覆蓋文件原有內(nèi)容
file(WRITE filename "message")
# 將message寫入filename文件中奈泪,會追加在文件末尾
file(APPEND filename "message")
# 從filename文件中讀取內(nèi)容并存儲到var變量中,如果指定了numBytes和offset灸芳,
# 則從offset處開始最多讀numBytes個字節(jié)段磨,另外如果指定了HEX參數(shù),則內(nèi)容會以十六進制形式存儲在var變量中
file(READ filename var [LIMIT numbytes] [OFFSET offset] [HEX])
# 重命名文件
file(RENAME <oldname> <newname>)
# 刪除文件耗绿,等于rm命令
file(REMOVE [file1 ...])
# 遞歸的執(zhí)行刪除文件命令苹支,等于rm -r
file(REMOVE_RECURSE [file1...])
# 根據(jù)指定的url下載文件
# timeout超時時間;下載的狀態(tài)會保存到status中误阻;下載日志會被保存到log债蜜;sum指定所下載文件預(yù)期的MD5值,如果指定會自動進行比對究反,
# 如果不一致寻定,則返回一個錯誤;SHOW_PROGRESS精耐,進度信息會以狀態(tài)信息的形式被打印出來
file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log] [EXPECTED_MD5 sum] [SHOW_PROGRESS])
# 創(chuàng)建目錄
file(MAKE_DIRECTORY [dir1 dir2 ...])
# 會把path轉(zhuǎn)換為以unix的/開頭的cmake風(fēng)格路徑狼速,保存到result中
file(TO_CMAKE_PATH path result)
# 它會把cmake風(fēng)格的路徑轉(zhuǎn)換為本地路徑風(fēng)格:windows下用"\",而unix下用"/"
file(TO_NATIVE_PATH path result)
# 將會為所有匹配查詢表達式的文件生成一個文件list卦停,并將該list存儲進變量variable里向胡,如果一個表達式指定了RELATIVE,返回的結(jié)果
# 將會是相對于定路徑的相對路徑惊完,查詢表達式例子:*.cxx僵芹,*.vt?
# NOTE:按照官方文檔的說法,不建議使用file的GLOB指令來收集工程的源文件
file(GLOB variable [RELATIVE path] [globbing expressions]...)
復(fù)制代碼
使用這種方式來指定源文件的話小槐,如果后面項目需要增加源文件拇派,比如項目中原本有2個源文件a.c和b.c,后面新增一個c.c,如果我們直接增加c.c件豌,然后進行編譯是會報錯的疮方,因為CMakeLists文件沒有改動,所以cmake不會重新生成makefile文件茧彤,所以我們需要簡單的改動一下CMakeLists文件骡显,可以在CMakeLists文件中添加一個空格,然后再編譯棘街,它就會生成makefile文件蟆盐。
9承边、常用命令-set_directory_properties
設(shè)置某個路徑的一種屬性:
set_directory_properties(PROPERTIES prop1 value1 prop2 value2)
復(fù)制代碼
prop1遭殉,prop2代表屬性,取值為:
- INCLUDE_DIRECTORIES
- LINK_DIRECTORIES
- INCLUDE_REGULAR_EXPRESSION
- ADDITIONAL_MAKE_CLEAN_FILES
10博助、常用命令-set_property
在給定的作用域內(nèi)設(shè)置一個命名的屬性:
set_property(<GLOBAL |
DIRECTORY [dir] |
TARGET [target ...] |
SOURCE [src1 ...] |
TEST [test1 ...] |
CACHE [entry1 ...]>
[APPEND]
PROPERTY <name> [value ...])
復(fù)制代碼
PROPERTY
參數(shù)是必須的险污。第一個參數(shù)決定了屬性可以影響的作用域:
- GLOBAL:全局作用域
- DIRECTORY:默認(rèn)當(dāng)前路徑,也可以用[dir]指定路徑富岳。
- TARGET:目標(biāo)作用域蛔糯,可以是0個或多個已有目標(biāo)。
- SOURCE:源文件作用域窖式,可以是0個或多個源文件蚁飒。
- TEST:測試作用域,可以是0個或多個已有的測試萝喘。
- CACHE:必須指定0個或多個cache中已有的條目淮逻。
11、多個源文件處理
cmake_minimum_required(VERSION 3.4.1)
# 查找當(dāng)前目錄所有源文件阁簸,并將名稱保存到 DIR_SRCS 變量
# 不能查找子目錄
aux_source_directory(. DIR_SRCS)
# 也可以使用
# file(GLOB DIR_SRCS *.c *.cpp)
add_library(
native-lib
SHARED
${DIR_SRCS})
復(fù)制代碼
如果源文件很多爬早,把所有文件一個個加入很麻煩,可以使用aux_source_directory命令或file命令启妹,會查找指定目錄下的所有源文件筛严,然后將結(jié)果存進指定變量名。
12饶米、多目錄多源文件處理
cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. DIR_SRCS)
# 添加child子目錄下的cmakelist
add_subdirectory(child)
add_library(
native_lib
SHARED
${DIR_SRCS})
target_link_libraries(native-lib child)
----------------------------------------
# child目錄下的CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. DIR_LIB_SRCS)
add_library(
child
SHARED
${DIR_LIB_SRCS})
復(fù)制代碼
- 主目錄中的CMakeLists.txt中添加add_subdirectory(child)命令桨啃,指明本項目包含一個子項目child。并在target_link_libraries指明本項目需要鏈接一個名為child的庫檬输。
- 子目錄child中創(chuàng)建CMakeLists.txt优幸,這里child編譯為共享庫。
13褪猛、添加預(yù)編譯庫
1)Android6.0版本以前
假設(shè)我們本地項目引用了libimported-lib.so:
cmake_minimum_required(VERSION 3.4.1)
# 使用 IMPORTED 標(biāo)志告知 CMake 只希望將庫導(dǎo)入到項目中
# 如果是靜態(tài)庫則將shared改為static
add_library(imported-lib
SHARED
IMPORTED)
# 參數(shù)分別為:庫网杆、屬性、導(dǎo)入地址、庫所在地址
set_target_properties(
imported-lib
PROPERTIES
IMPORTED_LOCATION
<路徑>/libimported-lib.so)
aux_source_directory(. DIR_SRCS)
add_library(
native-lib
SHARED
${DIR_SRCS})
target_link_libraries(native-lib imported-lib)
復(fù)制代碼
- 添加
add_library
命令碳却,第一個參數(shù)是模塊名队秩,第二個參數(shù)SHARED
表示動態(tài)庫,STATIC
表示靜態(tài)庫昼浦,第三個參數(shù)IMPORTED
表示以導(dǎo)入的形式添加馍资。 - 添加
set_target_properties
命令設(shè)置導(dǎo)入路徑屬性。 - 將
import-lib
添加到target_link_libraries
命令參數(shù)中关噪,表示native-lib需要鏈接imported-lib模塊
2)Android6.0版本以后
在Android6.0及以上版本鸟蟹,如果使用上節(jié)的方法添加預(yù)編譯動態(tài)庫的話,會有問題使兔,我們可以使用另外一種方式來配置:
# set命令定義一個變量
# CMAKE_C_FLAGS:c的參數(shù)建钥,會傳遞給編譯器
# 如果是c++文件,需要用CMAKE_CXX_FLAGS
# -L:庫的查找路徑
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[so所在目錄")
復(fù)制代碼
14虐沥、添加頭文件目錄
為了確保CMake可以在編譯時定位頭文件熊经,使用include_directories,相當(dāng)于g++選項中的-I
參數(shù)欲险。這樣就可以使用#include <xx.h>
镐依,否則需要使用#include "path/xx.h"
:
cmake_minimum_required(VERSION 3.4.1)
# 設(shè)置頭文件目錄
include_directories(<文件目錄>)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[so所在目錄]")
aux_source_directory(. DIR_SRCS)
add_library(
native-lib
SHARED
${DIR_SRCS})
target_link_libraries(native-lib imported-lib)
復(fù)制代碼
15、build.gradle配置
可以在gradle中使用arguments設(shè)置一些配置:
android{
defaultConfig{
cmake{
// 使用的編譯器clang/gcc
// cmake默認(rèn)就是 gnustl_static
arguments "-DANDROID_TOOLCHAIN=clang","-DANDROID_STL=gnustl_static"
// 指定cflags和cppflags天试,效果和cmakelist使用一樣
cFlags ""
cppFlags ""
// 指定需要編譯的cpu架構(gòu)
abiFilters "armeabi-v7a"
}
}
externalNativeBuild{
cmake{
// 指定CMakeLists.txt文件相對當(dāng)前build.gradle的路徑
path "xxx/CMakeLists.txt"
}
}
}
復(fù)制代碼
三槐壳、實操
官網(wǎng):www.fmod.com/ SDK下載頁面:www.fmod.com/download
需要先注冊登錄后,才能下載
1喜每、庫文件集成
在fmod官網(wǎng)下載好 fmodstudioapi20000android.tar.gz 后务唐,解壓,找到 api/core
目錄灼卢,其中inc
是fmod的頭文件绍哎,lib
是fmod預(yù)編譯好的so和jar文件璧亮。
1)集成so與jar
2)集成.h頭文件
2携龟、CMakeLists.txt文件配置:
fmod提供的so文件屬于預(yù)編譯庫,需要在自己的工程中集成fmod并使用俄烁,大概可分為2步驟:
- 指定頭文件目錄涩咖。方便在native-lib.cpp中可以使用
include <fmod.hpp>
- 指定預(yù)編譯庫目錄海诲。讓native-lib在編譯時,可以成功鏈接fmod檩互。
# 指定cmake最小支持版本
cmake_minimum_required(VERSION 3.4.1)
# 設(shè)置頭文件目錄
include_directories(${CMAKE_SOURCE_DIR}/inc)
# 設(shè)置第三方so庫路徑(android6.0以后需要這樣設(shè)置)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}")
# 添加一個庫特幔,根據(jù)native-lib.cpp源文件編譯一個native-lib的動態(tài)庫
add_library(
native-lib
SHARED
native-lib.cpp)
# 查找系統(tǒng)庫,這里查找的是系統(tǒng)日志庫闸昨,并賦值給變量log-lib
find_library(
log-lib
log)
# 設(shè)置以來的庫(第一個參數(shù)必須為目標(biāo)模塊蚯斯,順序不能換)
target_link_libraries(
native-lib
fmod
fmodL
${log-lib})
復(fù)制代碼
${CMAKE_SOURCE_DIR}
可以獲取到CMakeLists.txt文件當(dāng)前所在目錄路徑薄风。
3、build.gradle配置
因為該工具只在模擬器上運行拍嵌,所以只需要x86平臺的so庫文件遭赂,可以使用 abiFilters
進行過濾。
手機一般都是arm平臺横辆,可根據(jù)實際情況修改abiFilters撇他。
android {
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags ""
abiFilters "x86" // 指定本地庫的cpu架構(gòu)
}
}
ndk {
abiFilters "x86" // 指定第三方庫的cpu架構(gòu)
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
復(fù)制代碼
4、編寫native-lib.cpp
使用日志輸出fmod版本號:
#include <jni.h>
#include <string>
#include <android/log.h>
#include <fmod.hpp>
using namespace FMOD;
extern "C" JNIEXPORT jstring JNICALL
Java_com_lqr_cmakefmod_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
System *system;
System_Create(&system);
unsigned int version;
system->getVersion(&version);
__android_log_print(ANDROID_LOG_ERROR, "TEST", "FMOD Version: %08x", version);
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
復(fù)制代碼
最終狈蚤,在觸發(fā)stringFromJNI()方法后困肩,就可以在控制臺看到fmod版本號的輸出了。