AndroidStudio Cmake學(xué)習(xí)--如何漂亮的使用jni

隨著gradle的更新谜疤,對jni的支持越來越完善在张,大部分Android開發(fā)對于jni及C/C++的開發(fā)比較頭疼弛槐,因為沒有語法提示或者方法類名索引等教届。
原本我的幾個項目响鹃,都是在jni目錄定義的android.mk和application.mk,由于老版本的gradle對“-std=c++11”庫支持不夠案训,所以雖然能夠編譯买置,但是沒有語法高亮索引等,十分不爽强霎,gradle有出gradle-experimental版本是忿项,對C++編譯庫的支持增多了,但當時嫌麻煩城舞,最近在AS3.0和Gradle 4.1的使用中意外發(fā)現(xiàn)新創(chuàng)建工程對Native庫的支持,所以學(xué)習(xí)下轩触,有不足之處歡迎一起交流。

參考文檔家夺,多謝前輩引路

使用條件:

  1. 首先檢查自己的 Android Studio2.2以上及Android Plugin for Gradle 版本 2.2.0 或更高版本
  2. Android Studio目前默認的構(gòu)建工具是Cmake
  3. 在 build.properties里添加android.useDeprecatedNdk = true
  4. NDK工具
  5. CMake工具脱柱,可以在Android Studio中選擇下載
  6. LLDB:一種調(diào)試程序,可以在Android Studio中選擇下載拉馋, 使用它來調(diào)試原生代碼榨为。
ndk_tools.png

Cmake是什么

“CMake”即“cross platform make”,跨平臺安裝工具煌茴,可以通過簡單的命令語句來執(zhí)行構(gòu)建随闺,編譯,生成的操作蔓腐,他能夠輸出各種各樣的makefile或者project文件矩乐,能測試編譯器所支持的C++特性,類似UNIX下的automake。構(gòu)建的組態(tài)檔為CMakeLists.txt文件回论,CMake 支持 in-place 建構(gòu)(二進檔和源代碼在同一個目錄樹中)和 out-of-place 建構(gòu)(二進檔在別的目錄里)散罕,因此可以很容易從同一個源代碼目錄樹中建構(gòu)出多個二進檔。CMake 也支持靜態(tài)與動態(tài)程式庫的建構(gòu)傀蓉。

新的Cmake使用

有興趣的同學(xué)可以去研究AS對C++庫的支持
  • 使用CMake有2種情況笨使,

    • 一直是創(chuàng)建項目,新版AS創(chuàng)建流程中可以自己去選擇ndk-build和cmake構(gòu)建2個版本僚害,很簡單硫椰,自己去嘗試
    • 第二種是原有的native項目添加支持,接下來詳細介紹這種
      • 添加ndk-build支持時萨蚕,只需要在gradle Android 目錄下添加

           externalNativeBuild {
              ndkBuild {
                  path 'src/main/jni/Android.mk'  你的android.mk目錄靶草,application.mk放在同目錄即可被關(guān)聯(lián)
              }
          }
        
      • 添加cmake支持,同理岳遥,在gradle Android 指定CMakeLists.txt的目錄

           externalNativeBuild {
              cmake {
                  path "CMakeLists.txt"
              }
          } 
        
  • CMake在gradle的配置簡介

      android {
        defaultConfig {    
          // This block is different from the one you use to link Gradle
          // to your CMake or ndk-build script.
          externalNativeBuild {
            // For ndk-build, instead use ndkBuild {}
            cmake {
              // Cmake可選參數(shù)
              arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
      
              // 選擇C編譯的標記奕翔,選一個即可
              cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
      
              // C ++宏常量格式
              cppFlags "-D__STDC_FORMAT_MACROS"
            }
          }
           ndk {
            // 指定編譯的ABI,選擇你項目需要的abi即可
            abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                         'arm64-v8a'
          }
        }
      
        buildTypes {...}
          //分包打包浩蓉,可指定不同的編譯版本
        productFlavors {   
          one {
            externalNativeBuild {
              cmake {
                targets "native-lib-1"
              }
            }
          }
          two {     
            externalNativeBuild {
              cmake {        
                targets "native-lib-2"
              }
            }
          }
        }
          // 你的cmake地址
          externalNativeBuild {
              cmake {
                  path "CMakeLists.txt"
              }
          } 
      }
    

Cmake語法介紹

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp 
             
             # 可以使用${ANDROID_NDK}替代符指定路徑
             ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c 
             )
             

# 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.
# 引用 NDK 庫
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 )
          
              
# 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.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
                       
#添加其他預(yù)構(gòu)建庫   您需要使用 IMPORTED 標志告知 CMake 您只希望將庫導(dǎo)入到項目中 然后派继,您需要使用 set_target_properties() 命令指定庫的路徑       
add_library( imported-lib
             SHARED
             IMPORTED )     

#某些庫為特定的 CPU 架構(gòu)(或應(yīng)用二進制接口 (ABI))提供了單獨的軟件包宾袜,
#并將其組織到單獨的目錄中。此方法既有助于庫充分利用特定的 CPU 架構(gòu)驾窟,又能讓您僅使用所需的庫版本庆猫。
#要向 CMake 構(gòu)建腳本中添加庫的多個 ABI 版本,而不必為庫的每個版本編寫多個命令绅络,
#您可以使用 ANDROID_ABI 路徑變量月培。此變量使用 NDK 支持的一組默認 ABI,
#或者您手動配置 Gradle 而讓其使用的一組經(jīng)過篩選的 ABI恩急。例如:
add_library(...)
set_target_properties( # Specifies the target library.
                       imported-lib

                       # Specifies the parameter you want to define.
                       PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                       imported-lib/src/${ANDROID_ABI}/libimported-lib.so )     

# add_library() 向您的 CMake 構(gòu)建腳本添加源文件或庫時杉畜,
# Android Studio 還會在您同步項目后在 Project 視圖下顯示關(guān)聯(lián)的標頭文件。
#不過衷恭,為了確保 CMake 可以在編譯時定位您的標頭文件此叠,
#您需要將 include_directories() 命令添加到 CMake 構(gòu)建腳本中并指定標頭的路徑
include_directories(src/main/cpp/include/)

#要將預(yù)構(gòu)建庫關(guān)聯(lián)到您自己的原生庫,請將其添加到 CMake 構(gòu)建腳本的 target_link_libraries() 命令中:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )                       
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末随珠,一起剝皮案震驚了整個濱河市拌蜘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牙丽,老刑警劉巖简卧,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異烤芦,居然都是意外死亡举娩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門构罗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铜涉,“玉大人,你說我怎么就攤上這事遂唧≤酱” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵盖彭,是天一觀的道長纹烹。 經(jīng)常有香客問我,道長召边,這世上最難降的妖魔是什么铺呵? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮隧熙,結(jié)果婚禮上片挂,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好音念,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布沪饺。 她就那樣靜靜地躺著,像睡著了一般闷愤。 火紅的嫁衣襯著肌膚如雪整葡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天肝谭,我揣著相機與錄音掘宪,去河邊找鬼蛾扇。 笑死攘烛,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的镀首。 我是一名探鬼主播坟漱,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼更哄!你這毒婦竟也來了芋齿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤成翩,失蹤者是張志新(化名)和其女友劉穎觅捆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麻敌,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡栅炒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了术羔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赢赊。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖级历,靈堂內(nèi)的尸體忽然破棺而出释移,到底是詐尸還是另有隱情,我是刑警寧澤寥殖,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布玩讳,位于F島的核電站,受9級特大地震影響嚼贡,放射性物質(zhì)發(fā)生泄漏锋边。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一编曼、第九天 我趴在偏房一處隱蔽的房頂上張望豆巨。 院中可真熱鬧,春花似錦掐场、人聲如沸往扔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萍膛。三九已至吭服,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝗罗,已是汗流浹背艇棕。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留串塑,地道東北人沼琉。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像桩匪,于是被迫代替她去往敵國和親打瘪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容