一.CMake語法
- CMake語法非常多,我們知道如何導入靜態庫和動態庫以及最基礎的使用,目前是夠用的。其它方面則根據實際項目同步學習。
1.1.基礎語法-常用
- cmake_minimum_required:指定cmake最小版本
- include_directories:引入(原生代碼或庫的)頭文件
- add_library:主要作用:將指定的源文件生成鏈接文件,然后添加到工程中去
- find_library:引入NDK中的標準庫
- target_link_libraries:將預構建庫關聯到原生庫
- aux_source_directory:查找在某個路徑下的所有源文件
1.2.原生庫導入
- 有兩種方案
- 1.直接在target_link_libraries添加;
- 2.先使用find_library,然后結合target_link_libraries;
1.3.從原生代碼構建一個原生庫
- 使用add_library和target_link_libraries配合使用;
- 如:假設調用System.loadLibrary(“practiceffmpegplayer”),則在CMakeLists.txt中使用add_library(practiceffmpegplayer SHARED native-lib.cpp),然后使用target_link_libraries(practiceffmpegplayer);
- System.loadLibrary定義的庫名稱必須要和add_library中的第一個參數名稱一樣;
1.4.動態庫或靜態庫導入
- 分3步
- 1.指定靜態庫或動態庫的頭文件路徑,調用include_directories(路徑);
- 2.設置環境變量(寫法幾乎固定,跟也要結合實際情況來調整):
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}")
- 3.在target_link_libraries中添加靜態庫或動態庫的名字
- 注意:別忘記配置build.gradle,如下圖:
1.5.aux_source_directory方法的使用
- 語法
aux_source_directory(<dir> <variable>)
<dir>:要掃描的目錄(實踐過相對路徑,不會遞歸包含子目錄,僅包含指定的dir目錄)。
<variable>:存儲找到的源文件列表的變量名。
- 如:收集 src/ 目錄下的所有源文件
aux_source_directory(src SOURCE_FILES)
//繼續調用add_library方法
add_library(native-lib SHARED ${SOURCE_FILES})
二.創建支持Ffmpeg的Android項目
-
創建native項目,在native-cpp文件中掉用ffmpeg提供的一個方法,打印ffmpeg編譯配置信息。第一節中除了靜態庫和aux_source_directory未在項目中使用到,其它的都進行了使用,并做了詳細的注釋。gradle的修改在1.3中有詳細的截圖信息,重點關注CMakeLists.txt文件。
-
運行效果
-
CMakeLists.txt文件
#設置此項目所需的最低CMake版本。
cmake_minimum_required(VERSION 3.22.1)#include_directories:指定 原生代碼 或 so庫 的頭文件路徑
#添加頭文件路徑(相對于本文件路徑)
include_directories(include)#聲明項目名稱。
project("ffmpeg_simple01")#find_library:將一個變量和Android NDK的某個庫建立關聯關系。該函數的第二個參數為Android NDK中對應的庫名稱,
#而調用該方法之后,它就被和第一個參數所指定的變量關聯在一起。 在這種關聯建立以后,我們就可以使用這個變量在構建腳本的其它部分引用該變量所關聯的NDK庫。
find_library(log-liblog)#CMAKE_SOURCE_DIR 表示的是CMakeLists.txt所在的路徑
#message("============================= 1 =============================")
#message("${CMAKE_CXX_FLAGS}")
#message("============================= 2 =============================")
#message("${CMAKE_SOURCE_DIR}")
#message("============================= 3 =============================")
#message("${ANDROID_ABI}")
#message("${CMAKE_HOME_DIRECTORY}/libs/${ANDROID_ABI}")
#設置環境變量 結合include_directories(include),最后在target_link_libraries中添加靜態庫或動態庫的名字,就可以實現引入第三方靜態庫或動態庫
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}")#add_library:添加 源文件或庫
#創建可執行文件或庫的目標
#第一個參數,決定了最終生成的共享庫的名字
#第二個參數,我們可以指定根據源文件編譯出來的是靜態庫還是共享庫,分別對應STATIC/SHARED關鍵字
#第三個參數,指定源文件 (為IMPORTED時則表示是外部預編譯的)#創建并命名一個庫(構建一個原生庫)
#在 Android 中調用 System.loadLibrary("ffmpeg_simple01") 時,庫名稱 必須 與 CMakeLists.txt 中定義的目標庫名稱 完全匹配。即add_library中的第一個參數不能隨便定義
#在這個頂級CMakeLists.txt中,${CMAKE_PROJECT_NAME}用于定義目標庫名稱;
add_library(${CMAKE_PROJECT_NAME} SHARED native-lib.cpp)#將預構建庫關聯到原生庫
#指定CMake應鏈接到目標庫的庫。可以鏈接來自不同來源的庫,例如本文中定義的庫構建腳本、預構建的第三方庫或Android系統庫。
target_link_libraries(${CMAKE_PROJECT_NAME}avcodecavformatavutilswresampleswscaleandroid${log-lib})
- 代碼相關
三.總結
- 本篇文章記錄了最常用的CMake語法,以及在Android項目的使用。