Android JNI之青春期 Cmake(android studio)

緣起

生活不止眼前的茍且,還有詩與遠(yuǎn)方。如果你是個(gè)菜鳥,想成為一個(gè)萬人敬仰的大神,那么你不妨先給自己定個(gè)小目標(biāo),比如說先活它個(gè)200年,然后向天再借500年。嗯,第一次聽到它的時(shí)候,一顆心不停的顫抖,好像前生彼此曾擁有,今生卻等了很久很久??缙脚_(tái)作業(yè)的腳本,簡單的風(fēng)格,正處于青春期的 cmake,蓬勃的生機(jī)與活力,讓人忍不住為之著迷。

介紹

Cmake 是什么?巨頭百度說了:
CMake 是一個(gè)跨平臺(tái)的安裝工具,可以用簡單的語句來描述所有平臺(tái)的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project文件,能測試所支持的C++特性,類似UNIX下的automake。CMake 可以編譯、制作、產(chǎn)生適配器(wrapper)、還可以用任意的順序建構(gòu)。CMake 支持 in-place 建構(gòu)(二進(jìn)檔和源代碼在同一個(gè)目錄樹中)和 out-of-place 建構(gòu)(二進(jìn)檔在別的目錄里),因此可以很容易從同一個(gè)源代碼目錄樹中建構(gòu)出多個(gè)二進(jìn)檔。CMake 也支持靜態(tài)與動(dòng)態(tài)程式庫的建構(gòu)?!癈Make”這個(gè)名字是“cross platform make”的縮寫。
簡單而言,對(duì)于我們,就是生成so。

準(zhǔn)備工作

對(duì)于 cmake,as 的支持來得有點(diǎn)晚,直到 as 2.2 之后才開始。所以 as 較低版本的,請(qǐng)升級(jí),如有不便,請(qǐng)聯(lián)系谷歌客服。升級(jí)完畢,打開 SDKManager,還有幾個(gè)小插件需要安裝。比如說 cmake 插件,這個(gè)你不裝不行,如果,假如說如果,不好意思這里沒有如果。比如說 NDK 插件,套用官方的話說,原生開發(fā)工具包,允許您為 Android 使用 C 和 C++ 代碼,并提供眾多平臺(tái)庫。比如說 LLDB 插件,調(diào)試原生代碼,可選項(xiàng),推薦使用。


勾選情況圖

上圖,從官網(wǎng)文檔截取,請(qǐng)自主勾選需要項(xiàng)。如果你嫌煩,一鍵勾選所有,耐心等待個(gè)三天三夜,我連手帶腳支持。

征程開始

出師未捷身先死,啊呸,這個(gè),這個(gè)我們還是回歸正題,開始我們的 hello jni 征途。一個(gè)目標(biāo)(項(xiàng)目支持 cmake),兩條途徑。其中一條捷徑,創(chuàng)建一個(gè)新項(xiàng)目,選中 Include C++ Support 復(fù)選框。對(duì)于這種方式,沒什么需要解釋的,下一步,下一步。


Include C++ Support 復(fù)選框

另外一條就是在已有項(xiàng)目中支持 cmake,分幾個(gè)步驟。
步驟1. 在 src/main 目錄下創(chuàng)建一個(gè)目錄,取名叫 cpp。這個(gè)命名隨意,你喜歡就好。把需要引入的代碼放入創(chuàng)建的目錄下,這里千萬別隨意,不能鬧情緒。
步驟2. 創(chuàng)建 CMake 構(gòu)建腳本,一個(gè)純文本文件,取名 CMakeLists.txt,這個(gè)命名固定格式,不允許有脾氣。至于這個(gè)文件你放哪里,隨你喜歡好了。


我的選擇

步驟3. 在 app module 中的 build.gradle 文件中,給予 cmake 支持。
android{
    ...
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }
}

第一個(gè)配置,聲明 Native Build 方式為 cmake,并指定 cmake 腳本路徑。

android{
    ...
    defaultConfig{
      ...
      externalNativeBuild {
            cmake {
                cppFlags "-std=c++11 -frtti -fexceptions"
            }
        }
    }
}

喲喲,走過路過看過別錯(cuò)過。第二個(gè)配置,設(shè)置 cmake 編譯的條件,比如說 c11++ 標(biāo)準(zhǔn)。同樣都是 externalNativeBuild,這里是在 defaultConfig 域,而 cmake path 是 android 域。我有時(shí)候想,為什么不合二為一呢,非要讓人寫兩遍,頭疼,此處不求甚解。

征途關(guān)鍵,cmake 的配置

cmake 的文檔,E文,讓人沉醉于其中,不能自拔。有這么幾個(gè) api,比較重要。
重要1. add_library,生成 lib。對(duì)于我們而言,System.loadLibrary("xxx"),這里的 xxx 就是我們的lib。 示例如下:

# 創(chuàng)建一個(gè) lib,靜態(tài) or 動(dòng)態(tài),可創(chuàng)建多個(gè)
add_library( # lib名稱
             JniDemo

             # lib類型
             SHARED

             # .c/cpp目錄
             jni_dynamic.cpp )

重要2. set_target_properties,用來使用 .a 等已構(gòu)建好的 lib。示例如下:

# 添加自己的 lib 庫
add_library( libHello
             SHARED
             # 由于.a 已經(jīng)屬于已經(jīng)構(gòu)建好的庫,使用 IMPORTED 標(biāo)志,告訴 cmake 不需要編譯了
             IMPORTED )

set_target_properties(
                    #名稱
                    libHello

                    # 指定要定義的參數(shù).
                    PROPERTIES IMPORTED_LOCATION

                    # 導(dǎo)入 lib 的路徑
                    ${CMAKE_SOURCE_DIR}/sources/${ANDROID_ABI}/libHello.a)

重要3. find_library,查找 lib。示例如下:

# 搜索 NDK 指定 lib
find_library( # lib 路徑變量的名稱。
              log-lib

              # 查找指定 lib 名稱
              log )

重要4. target_link_libraries,鏈接所有 lib,生成新的 lib,示例如下:

# 鏈接庫
target_link_libraries( # 指定目標(biāo) lib
                       JniDemo

                       # 自己的 lib
                       libHello

                       # NDK log lib  //這里放 find 的路徑 ${log-lib} 也是可以
                       log )

暫且就講這么幾個(gè),基本上應(yīng)該也差不多可以滿足了。如果,那么請(qǐng)自覺查看 cmake 文檔,我想你會(huì)喜歡的。這里有個(gè)事還是提一下,對(duì)于上邊四個(gè)重點(diǎn),有兩個(gè)是重中之重。重點(diǎn)1,是生成 lib,建立 java 與 c/c++ 之間的橋梁。重點(diǎn)4, 是鏈接所有 lib, 建立一個(gè)完整的可運(yùn)行 lib。這兩個(gè),基本也可以解決問題了。至于多余的兩個(gè)重點(diǎn),為了結(jié)構(gòu)比較清晰,直觀罷了。

分享征途喜悅

到了這,jni 就告一段路了。至于前邊想的,算是有一個(gè)可喜的圓滿結(jié)局了。我之所以這么認(rèn)真的待 jni,是因?yàn)槲以敢?,我喜歡。若能以此換回對(duì) jni 的認(rèn)知,了解,固然可喜。如是沒有,我也沒有什么可后悔的了。
附送一張github機(jī)票,帶你領(lǐng)略世界的浩瀚

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容