NDK开发之CMake编译构建原生库
生活随笔
收集整理的這篇文章主要介紹了
NDK开发之CMake编译构建原生库
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
參考地址:https://blog.csdn.net/liu3364575/article/details/80091506
????????????????https://blog.csdn.net/qq_34902522/article/details/78104610在原作者的基礎上跑了一遍,將一些圖片轉化為代碼塊。將一些坑標注出來。
前言
Android NDK開發可能在平時的項目開發中不常用到,但是這并不代表其不重要, 相反NDK開發是Android開發人員的進階過程中必須要掌握的技能。 Android NDK是一組允許將C或C++(原生代碼)嵌入到Android應用中的工具。 如果開發者在需要以下操作的時候,使用NDK開發特別有用: * 在平臺之間移植其應用 * 從設備獲取卓越性能以用于計算密集型應用,例如游戲或物理模擬。 * 重復使用現有庫或者提供自己庫供重復使用。 除此之外,對于ndk的學習,也有助于加深開發者在閱讀框架的源碼理解。 ndk開發有兩種編譯方式,一種是通過ndk-build來構建;參考地址。 一種是通過CMake構建原生庫。通過CMake構建原生庫是Google新提出來的方式,比較方便、強大。準備
通過cmake進行ndk開發首先有個要求,需要Android Studio的版本是2.2以上版本(包含2.2) ,Gradle的版本需要升到2.2.0及以上。 滿足上面的條件下,我們需要下載ndk和構建工具。如下圖: 紅線標記的三個工具下載好就行。CMake和NDK就不說了,都好理解, LLDB呢是一種調試程序,用來調試原生代碼的。向項目添加原生代碼
上面的準備工作做完之后就可以向項目中添加原生代碼,構建原生庫進行ndk開發了。 這邊有個討論,向項目中添加原生代碼有兩種情況: 一種是新建一個新的項目支持C/C++; 一種是在已有項目中添加原生代碼。 所以這邊相應的也有兩種方式。先說第一種方式。1.創建支持C/C++的新項目
創建支持原生代碼的新項目跟平常開發中創建一個新項目沒有太大的區別,說一下不同的地方。 1.前者在向導的Config your new project界面需要選中 Include C++ Support 復選框。如圖1:?
2.前者在向導的Customize C++ Support 界面會有C++ Standard 的選擇 意思是你希望使用哪種 C++ 標準。 選擇 Toolchain Default 會使用默認的 CMake 設置。 這里我們選擇默認的。 Exceptions Support:如果你希望啟用對 C++ 異常處理的支持,請選中此復選框。 如果啟用此復選框,Android Studio 會將 -fexceptions 標志添加到模塊級 build.gradle 文件的 cppFlags 中,Gradle 會將其傳遞到 CMake。 Runtime Type Information Support:如果你希望支持 RTTI,請選中此復選框。 如果啟用此復選框,Android Studio 會將 -frtti 標志添加到模塊級 build.gradle 文件的 cppFlags 中,Gradle 會將其傳遞到 CMake。 這里自己看需求選擇勾不勾選,這邊演示的demo選擇勾選。如圖2:
創建項目完成之后,在as的左側項目結構目錄中的app應用模塊中可以看到cpp文件夾, cpp文件件里面存放有屬于項目的所有原生源文件、標頭和預構建庫。 對于新項目,Android Studio 會創建一個示例 C++ 源文件 native-lib.cpp 除了cpp文件夾之外,我們還看到一個CMakeLists.txt的這樣一個文件。 這個文件是CMake的構建腳本,下面會詳細說,這里就暫且不說。 之前有說過新建支持C/C++的項目會提供了一個示例的c++源文件native-lib.cpp,存放在cpp文件夾中 ,我們點開看看內容。 #include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_cmaketestone_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str()); }
恩,是使用C++寫的一個方法,返回一個"Hello from C++",我們跟蹤進去這個方法,看看哪里調用。 package com.cmaketestone;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView;public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup. static {System.loadLibrary("native-lib");}@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// Example of a call to a native method TextView tv = (TextView) findViewById(R.id.sample_text);tv.setText(stringFromJNI());}/** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); }
我們發現,這個原生方法是在MainActivity中調用的,返回的字符串設置給了TextView。 通過這兩張圖我們發現,原生方法通過native關鍵字來表示、在使用原生庫之前, 需要通過System.loadLibrary(“庫名稱”)加載、 原生方法的方法名命名等常見要點。這邊就一筆略過。因為本文重點是CMake構建原生庫。 所以ndk的一些基礎知識,以及JNI等,就不細說。本文假設讀者知道這些。 這樣的一個新的支持原生代碼的項目創建之后,并且還自帶demo,開發者就可以很方便在上面進行開發。 假設現在要創建一個原生庫進行ndk開發,我們在cpp文件夾下new一個C/C++ Source file , 在你new出來的文件編寫你的C/C++代碼邏輯,然后在CMakeLists.txt配置文件上稍作配置,即可。 下面會詳述CMakeLists.txt的配置。
- 項目添加原生代碼
第二步,我們創建CMake構建腳本,也就是CMakeLists.txt文件,在 應用模塊下new一個file文件, 命名為CMakeLists.txt即可, 注意哦,這個文 件的名稱和路徑不能搞錯哦。CMakeLists.txt創建好打開后,發現沒有任何內容,這就對了。。 需要我們自己配置的。 不像是通過第一種新創建支持原生代碼的項目那種,還給你寫好,不過我們可以參考第一種方式下,系統給我們 默認生成的內容。 咱們看一下第一種方式下,系統默認生成的CMakeLists.txt文件的內容是什么樣子吧。如圖: # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.4.1)#CMake 最低版本要求,# 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 )# 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 )# 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} )
通過圖片我們看到,其實內容也沒什么。就cmake_minimum_required()、add_library() 、find_library、target_link_libraries()。這幾個CMake命令,每個CMake命令都有英文介紹很好理解。 比如add_library創建和命名一個庫,這邊名稱我們就填test-lib,種類分為static和shared, 具體區別嘛移步:
static和shared的區別
這里我們選擇SHARED,然后就是提供一個library的相對路徑。只有在CMakeLists.txt文件中配置了該命令 ,才能找到編譯這個庫。 其他的一些CMake命令大家自行搜索了解,都不是很難,很好理解,這里篇幅有限就不細說了。 那現在我們可以按照系統提供的模板,基于自己的項目寫了一份CMakeLists.txt文件,代碼如下:這里我這邊寫了一個NdkHelper類,專門用來定義native方法的:?
package com.cmaketestdemo;/** * Author:wang_sir * Time:2018/5/31 11:54 * Description:This is NdkHolder */ public class NdkHolder {static {System.loadLibrary("test-lib");}public native String stringFromJNI(); }這一步做完后,第二步也算告一段落了,現在我們來看第三步:將 Gradle 關聯到你的原生庫。?
通過as的快捷鍵來實現的,右鍵點擊你想要關聯到原生庫的模塊(例如 app 模塊),?
并從菜單中選擇 Link C++ Project with Gradle。?
BuildSystem選擇CMake,projectpath就是CMakeLists.txt文件的路徑。點擊ok完成。?
你會在應用模塊的build.gradle文件中發現,android閉包里出現 externalNativeBuild {cmake {path 'CMakeLists.txt'}}
可以看到編譯生成的.so文件。
總結
以上是生活随笔為你收集整理的NDK开发之CMake编译构建原生库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DSPACE模拟简单事故现场
- 下一篇: 《九阴真经》正本和九阳真经