Android NDK(JNI)詳解教程一 CMakeLists.txt 詳解

什么是NDK、JNI

  • JNI
    Java Native Interface,即 Java 本地接口,可以理解為在 Java 中調用 C/C++ 代碼、在 C/C++ 中調用 Java 代碼,JNI 是 Java 的,和 Android 無關
  • NDK
    Native Development Kit,Android NDK 是一個工具集,可讓您使用 C 和 C++ 等語言以原生代碼實現應用的各個部分,NDK 可以理解為 Android 中實現 JNI 的一種手段,通過 NDK,還可以打包 C/C++ 動態(tài)庫,并自動打包進 APK/AAR 中

CMakeLists.txt 是什么?

  • Android Studio 新建項目的時候可以選擇各種各樣的模板,選擇 Native C++ 模板就可以創(chuàng)建一個簡單的 NDK 項目
    在 app/src/main/cpp 下可以看到有 CMakeLists.txt 和 native-lib.cpp。
  • 當只有一個源文件時,直接使用gcc命令就可以直接編譯,如果有很多源文件、團隊成員多個時,直接使用gcc命令編譯就非常繁瑣;這個時候make指令應運而生,可以多人編輯同一個編譯規(guī)則文件后,make工具依照這個編譯規(guī)則文件進行編譯,源文件、目標文件、目標類型等等都在該文件中體現,這個文件就是makefile文件;但是慢慢地大家發(fā)現大項目時編寫makefile文件依然是一個繁瑣容易出錯的事情,這個時候cmake工具就出現了,它可以依據簡單的配置文件自動生成makefile、project等文件,這個配置文件就是 CMakeLists.txt !很顯然,相對于編寫makefile文件,編寫cmakelists文件要簡單的多。
  • CMakeLists.txt + cmake -> makefile;makefile + make -> 編譯出目標結果

CMakeLists.txt 詳解

  • 常用變量
    PROJECT_NAME: 用函數project(demo)指定的項目名稱,這里變量的值為demo
    PROJECT_SOURCE_DIR: 工程的根目錄
    PROJECT_BINARY_DIR: 執(zhí)行cmake命令的目錄,如果mkdir build ,cd build, cmake ../,的話,該變量的值為build目錄
    CMAKE_CURRENT_SOURCE_DIR:當前處理的CMakeLists.txt文件所在目錄
    CMAKE_CURRENT_BINARY_DIR: cmake當前正在處理的二進制目錄
    CMAKE_CURRENT_LIST_DIR: CMakeLists.txt的完整路徑
    CMAKE_CURRENT_LIST_LINE: 當前所在行
    CMAKE_C_FLAGS: 設置C編譯選項
    CMAKE_CXX_FLAGS:設置C++編譯選項
    CMAKE_INSTALL_PREFIX: 指定install指令安裝文件的根目錄
    EXECUTABLE_OUTPUT_PATH: 生成目標可執(zhí)行文件的輸出位置
    LIBRARY_OUTPUT_PATH: 庫文件輸出位置

  • 指定cmake最小版本:(必須設置)

cmake_minimum_required(VERSION 3.10.2)
  • 設置項目名稱:(必須設置)
project("projectname")
  • 設置編譯類型:(必須設置)
add_executable(projectname native-lib.cpp) //生成可執(zhí)行文件
add_library(projectname STATIC native-lib.cpp) //生成靜態(tài)庫(默認)
add_library(projectname SHARED native-lib.cpp) //生成動態(tài)庫
  • 制定編譯包含的源文件(必須設置)
    1.明確指定源文件
add_library(projectname SHARED native-lib.cpp)

2.搜索指定目錄下所有源文件(不會遞歸遍歷子目錄)

//搜索一個目錄下所有的源代碼文件,并將列表存儲再一個變量中
aux_source_directory(. SRC_LIST)
add_library(projectname SHARED ${SRC_LIST})

3.自定義搜索源文件規(guī)則(推薦使用 aux_source_directory,不推薦使用 file)

//搜索一個目錄下所有的源代碼文件,并將列表存儲再一個變量中
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_LIST "*.c")
file(GLOB SRC_LIST "src/*.cpp")
aux_source_directory(src SRC_PROTOCOL_LIST)
add_library(projectname SHARED ${SRC_LIST})
  • 查找指定的庫文件
// find_library(VAR name path)查找到指定的預編譯庫,并將它的路徑存儲在變量中。
// 默認的搜索路徑為cmake 包含的系統庫,因此如果是NDK的公共庫只需要指定庫的name即可。
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

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)
  • 設置包含的目錄(編譯環(huán)境、頭文件等)
include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)
  • 設置鏈接庫的搜索目錄
link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)
  • 設置target需要連接的庫(${log-lib}也可以使用絕對路徑、指定鏈接多個庫在${log-lib}后換行追加即可)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        projectname

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
  • set 常用指令
set(SRC_LIST main.cpp test1.cpp) //設置源代碼變量
set(SRC_LIST test2.cpp) //追加
set(EXECUTABLE_OUTPUT_PATH [path]) //設置可執(zhí)行文件的輸出路徑
set(LIBRARY_OUTPUT_PATH [output_path]) //設置庫文件的輸出路徑
set(CMAKE_CXX_FLAGS "-Wall std=c++11") //設置C++編譯參數
  • 打印信息
message(${PROJECT_SOURCE_DIR})
message("build with debug mode")
message(WARNING "this is warnning message")
  • 條件控制
    1.if...elseif...else...endif
    2.while...endwhile
    3.foreach...endforeach

  • 多目錄、多源文件、多CMakeLists.txt
    主CMakeLists.txt

...
#添加child目錄
add_subdirectory(child)
...
target_link_libraries( # Specifies the target library.
        projectname
        child
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

子CMakeLists.txt

#child目錄下的CMakeLists.txt
...
aux_source_directory(. DIR_SRCS)
...
add_library(
        child
        SHARED
        ${DIR_SRCS}
)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容