Android NDK 跨平臺構建工具 CMake 使用筆記

一、CMake 介紹

CMake是一個跨平臺的安裝/編譯工具,通過CMake我們可以通過簡單的語句來描述所有平臺的安裝/編譯過程。它能輸出各種makefile或者project文件,能測試編譯器所支持的C++特性,類似UNIX下的automake。Cmake 並不直接建構出最終的軟件,而是產生標準的建構檔(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然後再依一般的建構方式使用。這使得熟悉某個集成開發環境(IDE)的開發者可以用標準的方式建構他的軟件。

CMake的所有語句都寫在一個CMakeLists.txt文件中,CMakeLists.txt 文件編寫完成後,直接使用CMake命令進行運行即可 ,但是需要這個命令需要指向CMakeLists.txt 所在的目錄。在AndroidStudio中,IDE會幫我們執行命令,我們可以暫時不需要了解CMake和CmakeList.txt之間的關係,但是我們需要了解如何編寫CmakeList.txt 來配置我們的項目,以保證相關的庫能正常的加載和運行。

補充:在之前的Android NDK學習(二):編譯腳本語法Android.mk和Application.mk裏面我們講述過makefile相關的內容,感興趣的可以自行查看。

二、CMakeLists 指令

在講CMakeLists相關指令之前,可以看一下常見的CMakeLists.txt文件的內容,下面是使用CameraX+Rtmp開發推流功能的時候,創建的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.4.1)

set(rtmp_lib_src_DIR ${PROJECT_SOURCE_DIR}/src/main/cpp)

add_subdirectory(${rtmp_lib_src_DIR}/librtmp)

include_directories(
    ${CMAKE_SOURCE_DIR}/src/main/cpp/include
)

# build application's shared lib
# For Java Call, the file of C/C++ Use UpperCase Name Space
add_library(rtmp-push-lib SHARED
    ${CMAKE_SOURCE_DIR}/src/main/cpp/RtmpPushLib.cpp
    ...other cpps
) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -L${rtmp_lib_src_DIR}/libs/${ANDROID_ABI}") # Include libraries needed for MediaEditor lib target_link_libraries(rtmp-push-lib rtmp x264 android log ${log-lib} )

 下面我們根據上面的配置文件,來逐步講解各個指令的使用方式和意義:

1. cmake_minimum_required(VERSION 3.4.1) 指令

此指令的作用就是規定cmake程序的最低版本,屬於可選的指令,但是一般情況下都會添加這個指令。如果CMakeLists.txt中使用了一些高版本cmake特有的命令的時候,是必須要加上的,這樣能夠提醒使用者升級到該版本之後再執行camke。

2. set 指令

set指令用於顯式的定義變量。使用方式爲set(var [value] [cache type docstring] [force]). 其中定義時必須填寫的參數爲:var 和 value。

3. add_subdirectory 指令

用於添加需要編譯的源文件的子目錄;語法爲:add_subdirectory(source_dir [binary_dir][exclude_from_dir])。其中source_dir:向當前工程添加存放源文件的子目錄,[binary_dir]:指定目標文件存放的位置,[exclude_from_dir]:將該目錄從編譯過程中排除。

注意:子目錄也需要有CmakeLists.txt文件,以保證子目錄下的源文件能夠正常編譯。

4. add_library 指令

add_library():用於將一組源文件編譯生成一個庫文件,並保存爲 libname.so (lib 前綴是生成文件時 CMake自動添加上去的)。可傳入多個源文件,其語法爲:add_library(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] [source])。

其中生成的有三種庫文件類型,不寫的話,默認爲 STATIC。下面我們簡單的講解一下生成的庫文件類型:

  • SHARED:表示生成的爲動態庫,可以在Java代碼中使用System.loadLibaray(name)進行動態調用。
  • STATIC:表示生成的爲靜態庫,集成到代碼的時候,會在編譯時調用。
  • MODULE:只有在dyld的系統有效,如果不支持dyld,則會被當作SHARED對待。

5. find_library 指令

這個指令是Android NDK開發提供的特有的Cmake指令,用於添加NDK API。語法爲:find_library(<VAR> name1 path1 path2 ...)。例如上面的CMakeList.txt文件中,我們就添加了日誌支持的API。

6. target_link_libraries 指令

target_link_libraries 指令用來爲 target 添加需要鏈接的共享庫,同樣也可以用於爲自己編寫的共享庫添加共享庫鏈接。語法爲:target_link_libraries(target library <debug | optimized> library2…)

三、參考資料

Android NDK 開發:CMake 使用:https://www.jianshu.com/p/c71ec5d63f0d

CMakeLists入門學習筆記(一):https://blog.csdn.net/lisfaf/article/details/90639611

CMake 入門實戰:https://www.hahack.com/codes/cmake/

CMake 使用教程:https://www.jianshu.com/p/3078a4a195df

CMake使用簡介及CMakeList.txt編寫:https://www.pianshen.com/article/4159316635/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章